Heim > Artikel > Backend-Entwicklung > C#-Multithread-Parameterübergabe
1. Übergeben Sie die Entitätsklasse (Sie können mehrere Parameter übergeben und den Rückgabewert erhalten). Die Demo lautet wie folgt:
Funktion, die aufgerufen werden muss im Thread:
namespace ThreadParameterDemo { public class FunctionClass { public static string TestFunction(string name, int age) { //内部处理省略 return name + " 的年龄是:" + age; } } }
Eingekapselt durch Entitäten:
namespace ThreadParameterDemo { /// <summary> /// 过渡类 /// </summary> public class TransitionalClass { private string name = string.Empty; private int age; public string acceptResults = string.Empty; public TransitionalClass(string name, int age) { this.name = name; this.age = age; } public void TestFunction() { acceptResults = FunctionClass.TestFunction(this.name, this.age); } } }
Anruf:
private void Form1_Load(object sender, EventArgs e) { //实例化ThreadWithState类,为线程提供参数 TransitionalClass tc = new TransitionalClass(" Jack", 42); // 创建执行任务的线程,并执行 Thread t = new Thread(new ThreadStart(tc.TestFunction)); t.Start(); //获取返回值,通过 tc.acceptResults; }
Kleiner Hinweis:
Sie müssen auf das Problem von IsBackground achten, wenn IsBackground falsch ist, beendet das Windows-Programm den Thread nicht automatisch für Sie wenn es austritt. Das heißt, Ihre Bewerbung ist noch nicht beendet.
MSDN-Empfehlung: Der beste Weg, Parameter für Multithread-Methodenaufrufe bereitzustellen, besteht darin, die Zielmethode in eine Klasse zu packen und zu geben Die Klasse definiert Felder, die als Parameter für den neuen Thread verwendet werden.
Der Vorteil dieses Ansatzes besteht darin, dass Sie jedes Mal, wenn Sie einen neuen Thread starten möchten, eine neue Instanz der Klasse mit ihren eigenen Parametern erstellen können.
BackgroundWorker-Klasse
Die Funktionen in ThreadStart haben keinen Rückgabewert und keine Parameter
2. Parameter und Rückgabewerte in asynchronen Aufrufen
Die perfekte Lösung für Parameter und Rückgabewerte ist die Verwendung asynchroner Aufrufe. Im Vergleich zu Thread besteht einer der größten Nachteile asynchroner Aufrufe darin, dass sie ihre Priorität nicht steuern können.
Der spezifische Code lautet wie folgt:
public delegate string delegateFunction(string name,int age);//委托 delegateFunction df; private void Form1_Load(object sender, EventArgs e) { //指向需要调用的方法 df = new delegateFunction(FunctionClass.TestFunction); string name = "my name";//输入参数 int age = 19; IAsyncResult result = df.BeginInvoke(name,age, null, null); string myResult = df.EndInvoke(result);//用于接收返回值 MessageBox.Show(myResult); }
Vereinfacht :
public Func<string, int, string> df;//委托 private void Form1_Load(object sender, EventArgs e) { //指向需要调用的方法 df += FunctionClass.TestFunction; string name = "my name";//输入参数 int age = 19; IAsyncResult result = df.BeginInvoke(name, age, null, null); string myResult = df.EndInvoke(result);//用于接收返回值 MessageBox.Show(myResult); }
Kleiner Hinweis:
In auf diese Weise Der generierte neue Thread läuft im Hintergrund (Hintergrund) und die Priorität ist normal
3 . Verwenden Sie BackgroundWorker
Die einfachste Möglichkeit, einen Wert von mehreren Threads zurückzugeben, besteht darin, die BackgroundWorker-Komponente zum Verwalten von Threads zu verwenden, ein Ereignis auszulösen, wenn die Aufgabe abgeschlossen ist, und dann einen Ereignishandler zu verwenden um mit dem Ergebnis umzugehen.
Kleiner Hinweis:
Die BackgroundWorker-Komponente wird verwendet, um zeitaufwändige asynchrone Vorgänge wie Datenbanktransaktionen und Dateidownloads durchzuführen.
Fügen Sie eine BackgroundWorker-Instanz in der Anwendung hinzu. Wenn Sie VS verwenden, können Sie sie direkt aus dem Tool in die Anwendung ziehen:
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
Um den Betrieb im Hintergrund zu starten, müssen Sie die RunWorkerAsync()-Methode von BackgroundWorker aufrufen. Wenn diese Methode aufgerufen wird, beginnt BackgroundWorker mit der Ausführung von Hintergrundoperationen, indem er das DoWork-Ereignis auslöst in einem anderen Thread ausgeführt.
Wenn der Hintergrundvorgang abgeschlossen ist, wird das RunWorkerCompleted-Ereignis ausgelöst. Über diese Methode kann das Abschlussergebnis des Hintergrundvorgangs an den Benutzer zurückgegeben werden.
Verwenden Sie außerdem die Eigenschaft „Canceled“ der RunWorkerCompletedEventArgs-Instanz, um zu bestimmen, ob der Hintergrundvorgang aufgrund des Vorgangs „Abbrechen“ beendet wird.
Die spezifische Demo lautet wie folgt:
using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { //TransitionalClass tc = new TransitionalClass("xiaoming", 10); //ThreadPool.QueueUserWorkItem(new WaitCallback(TransitionalClass.TestFunction), tc); } private void button1_Click(object sender, EventArgs e) { this.TestArea2(); } private System.ComponentModel.BackgroundWorker BackgroundWorker1 = new System.ComponentModel.BackgroundWorker(); private void TestArea2() { InitializeBackgroundWorker(); AreaClass2 AreaObject2 = new AreaClass2(); AreaObject2.Base = 30; AreaObject2.Height = 40; // Start the asynchronous operation. BackgroundWorker1.RunWorkerAsync(AreaObject2); } private void InitializeBackgroundWorker() { // Attach event handlers to the BackgroundWorker object. BackgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(BackgroundWorker1_DoWork); BackgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker1_RunWorkerCompleted); } private void BackgroundWorker1_DoWork( object sender, System.ComponentModel.DoWorkEventArgs e) { //在执行DoWork 事件时,DoWorkEventArgs 实例的Result 属性,返回值到用户;在RunWorkerCompleted 事件里,RunWorkerCompletedEventArgs 实例的Result 属性接收值; AreaClass2 AreaObject2 = (AreaClass2)e.Argument; // Return the value through the Result property. e.Result = AreaObject2.CalcArea(); } private void BackgroundWorker1_RunWorkerCompleted( object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) { // Access the result through the Result property. double Area = (double)e.Result; MessageBox.Show("The area is: " + Area.ToString()); } } }
Demo-Code von MSDN: Klicken Sie hier, um den Link zu öffnen
Referenzartikel: Klicken Sie hier, um den Link zu öffnen
4 Wenn es nicht so gut ist wie der Rückgabewert, wie sollen wir es elegant schreiben? Anonyme Funktion
FunctionClass-Klasse hinzugefügt, die Testfunktion lautet wie folgt:
public static void TestFunction2(string name, int age) { //内部处理省略 }
Der Aufruf lautet wie folgt:
private void Form1_Load(object sender, EventArgs e) { Thread t1 = new Thread(new ThreadStart(delegate { FunctionClass.TestFunction2("eee", 5); })); t1.Start(); }
Kleiner Hinweis:
Wenn die Thread-Startfunktion über WCF aufgerufen wird, sollte sie auf dem Server platziert werden. Wenn sie auf dem Client platziert wird, kann es aufgrund der zeitlichen Begrenzung leicht zum Absturz des Hauptprogramms kommen WCF-Client.
Der Hauptgrund für den Absturz ist, dass die WCF-Reaktionszeit des Clients begrenzt ist.
Das Obige ist der Inhalt der C#-Multithread-Parameterübergabe. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!