Wie startet man einen Thread mit Parametern in C #?
c#
multithreading
J L.
quelle
quelle
Antworten:
Ja:
quelle
void MyParamObject(object myUrl){ //do stuff }
sollte Parametertyp habenobject
ParameterizedThreadStart
und dies eindeutig aus dem Fragentext hervorgeht, ist dies wahrscheinlich nicht der Fall.Bei einer der beiden Überladungen des Thread-Konstruktors wird ein ParameterizedThreadStart-Delegat verwendet, mit dem Sie einen einzelnen Parameter an die Startmethode übergeben können. Leider erlaubt es nur einen einzigen Parameter und dies auf unsichere Weise, da es als Objekt übergeben wird. Ich finde es viel einfacher, einen Lambda-Ausdruck zu verwenden, um die relevanten Parameter zu erfassen und sie stark typisiert zu übergeben.
Versuche Folgendes
quelle
Dim thr As New Thread(Sub() DoStuff(settings))
Sie können Lambda-Ausdrücke verwenden
Dies ist bisher die beste Antwort, die ich finden konnte. Sie ist schnell und einfach.
quelle
Der Parametertyp muss ein Objekt sein.
BEARBEITEN:
Obwohl diese Antwort nicht falsch ist, empfehle ich gegen diesen Ansatz. Die Verwendung eines Lambda-Ausdrucks ist viel einfacher zu lesen und erfordert keine Typumwandlung. Siehe hier: https://stackoverflow.com/a/1195915/52551
quelle
Parameter
?quelle
Einfache Möglichkeit mit Lambda wie so ..
ODER Sie könnten sogar
delegate
mit ,ThreadStart
wie so ...ODER mit VS 2019 .NET 4.5+ noch sauberer wie so ..
quelle
Verwenden Sie
ParametrizedThreadStart
.quelle
Verwenden Sie ParameterizedThreadStart .
quelle
Wie bereits in verschiedenen Antworten erwähnt, bietet die
Thread
Klasse derzeit (4.7.2) mehrere Konstruktoren und eineStart
Methode mit Überladungen.Diese relevanten Konstruktoren für diese Frage sind:
und
die entweder einen
ThreadStart
Delegierten oder einenParameterizedThreadStart
Delegierten nehmen.Die entsprechenden Delegierten sehen folgendermaßen aus:
Wie zu sehen ist, scheint der richtige Konstruktor derjenige zu sein, der einen
ParameterizedThreadStart
Delegaten nimmt, so dass eine Methode, die der angegebenen Signatur des Delegaten entspricht, vom Thread gestartet werden kann.Ein einfaches Beispiel für die Instanziierung der
Thread
Klasse wäreoder nur
Die Signatur der entsprechenden Methode (
Work
in diesem Beispiel aufgerufen ) sieht folgendermaßen aus:Was bleibt, ist den Thread zu starten. Dies erfolgt entweder mit
oder
Während
Start()
der Thread gestartet undnull
als Daten an die Methode übergeben würde,Start(...)
kann verwendet werden, um alles an dieWork
Methode des Threads zu übergeben.Bei diesem Ansatz gibt es jedoch ein großes Problem: Alles, was an die
Work
Methode übergeben wird, wird in ein Objekt umgewandelt. Das heißt, innerhalb derWork
Methode muss es wieder wie im folgenden Beispiel in den ursprünglichen Typ umgewandelt werden:Casting ist etwas, was Sie normalerweise nicht wollen.
Was ist, wenn jemand etwas anderes übergibt, das keine Zeichenfolge ist? Da dies zunächst nicht möglich zu sein scheint (weil es meine Methode ist, ich weiß, was ich tue oder die Methode privat ist, wie sollte jemand jemals etwas an sie weitergeben können? ), Können Sie möglicherweise aus verschiedenen Gründen genau diesen Fall haben . Da einige Fälle möglicherweise kein Problem darstellen, sind es andere. In solchen Fällen werden Sie wahrscheinlich eine haben,
InvalidCastException
die Sie wahrscheinlich nicht bemerken werden, weil sie den Thread einfach beendet.Als Lösung würden erwarten , dass Sie ein generisch erhalten
ParameterizedThreadStart
Delegierten wie ,ParameterizedThreadStart<T>
woT
die Daten der Typ , der Sie in denen geben wollen wäreWork
Methode. Leider gibt es so etwas (noch?) Nicht.Es gibt jedoch eine vorgeschlagene Lösung für dieses Problem. Dabei wird eine Klasse erstellt, die sowohl die an den Thread zu übergebenden Daten als auch die Methode enthält, die die Arbeitsmethode wie folgt darstellt:
Mit diesem Ansatz würden Sie den Thread folgendermaßen starten:
Auf diese Weise vermeiden Sie einfach das Herumwirbeln und haben eine typsichere Möglichkeit, Daten für einen Thread bereitzustellen ;-)
quelle
private static void MyMethod<T>(T myData) { T message = myData; Console.WriteLine($"the thread wrote: {message}"); }
message.Length
ist nicht möglich und so weiter)if(myData.GetType() == typeof(string)) { var str = ((string)(object)myData).Length; }
. Anstatt Ihre Threading-Methode zu verwendenTasks<T>
, fand ich die Verwendung etwas komfortabler , wie zum Beispieltasks.Add(Task.Run(() => Calculate(par1, par2, par3)))
meine Antwort unten ( stackoverflow.com/a/59777250/7586301 )Ich hatte ein Problem mit dem übergebenen Parameter. Ich habe eine Ganzzahl von einer for-Schleife an die Funktion übergeben und angezeigt, aber es wurden immer unterschiedliche Ergebnisse ausgegeben. wie (1,2,2,3) (1,2,3,3) (1,1,2,3) usw. mit ParametrizedThreadStart- Delegat.
Dieser einfache Code wirkte wie ein Zauber
quelle
Das
ParameterizedThreadStart
nimmt einen Parameter. Sie können damit einen Parameter oder eine benutzerdefinierte Klasse mit mehreren Eigenschaften senden.Eine andere Methode besteht darin, die Methode, die Sie als Instanzmitglied starten möchten, zusammen mit Eigenschaften für die Parameter, die Sie festlegen möchten, in eine Klasse einzufügen. Erstellen Sie eine Instanz der Klasse, legen Sie die Eigenschaften fest und starten Sie den Thread, der die Instanz und die Methode angibt. Die Methode kann dann auf die Eigenschaften zugreifen.
quelle
Sie können einen ParametrizedThreadStart- Delegaten verwenden:
quelle
Sie können die BackgroundWorker RunWorkerAsync- Methode verwenden und Ihren Wert übergeben.
quelle
quelle
Ich schlage vor,
Task<T>
anstelle von zu verwendenThread
; Es erlaubt mehrere Parameter und wird sehr gut ausgeführt.Hier ist ein Arbeitsbeispiel:
quelle
quelle