(1) Es besteht keine Notwendigkeit, Parameter zu übergeben oder zurückzugeben.
ThreadStart ist ein Delegat, der als void ThreadStart() definiert ist und keine Parameter und keinen Rückgabewert hat.
class Program { static void Main(string[] args) { for (int i = 0; i < 30; i++) { ThreadStart threadStart = new ThreadStart(Calculate); Thread thread = new Thread(threadStart); thread.Start(); } Thread.Sleep(2000); Console.Read(); } public static void Calculate() { DateTime time = DateTime.Now;//得到当前时间 Random ra = new Random();//随机数对象 Thread.Sleep(ra.Next(10,100));//随机休眠一段时间 Console.WriteLine(time.Minute + ":" + time.Millisecond); } }
(2) Ein einzelner Parameter muss übergeben werden
Der ParameterThreadStart-Delegat ist als void ParameterizedThreadStart(object state) definiert, der einen Parameter, aber keinen Rückgabewert hat.
class Program { static void Main(string[] args) { for (int i = 0; i < 30; i++) { ParameterizedThreadStart tStart = new ParameterizedThreadStart(Calculate); Thread thread = new Thread(tStart); thread.Start(i*10+10);//传递参数 } Thread.Sleep(2000); Console.Read(); } public static void Calculate(object arg) { Random ra = new Random();//随机数对象 Thread.Sleep(ra.Next(10, 100));//随机休眠一段时间 Console.WriteLine(arg); } }
(3) Verwenden Sie eine spezielle Thread-Klasse (häufig verwendet)
Die Verwendung einer Thread-Klasse kann mehrere Parameter und mehrere Rückgabewerte haben, was sehr flexibel ist!
class Program { static void Main(string[] args) { MyThread mt = new MyThread(100); ThreadStart threadStart = new ThreadStart(mt.Calculate); Thread thread = new Thread(threadStart); thread.Start(); //等待线程结束 while (thread.ThreadState != ThreadState.Stopped) { Thread.Sleep(10); } Console.WriteLine(mt.Result);//打印返回值 Console.Read(); } } public class MyThread//线程类 { public int Parame { set; get; }//参数 public int Result { set; get; }//返回值 //构造函数 public MyThread(int parame) { this.Parame = parame; } //线程执行方法 public void Calculate() { Random ra = new Random();//随机数对象 Thread.Sleep(ra.Next(10, 100));//随机休眠一段时间 Console.WriteLine(this.Parame); this.Result = this.Parame * ra.Next(10, 100); } }
(4) Verwenden Sie anonyme Methoden (häufig verwendet)
Die Verwendung anonymer Methoden zum Starten von Threads kann mehrere Parameter und Rückgabewerte haben und ist sehr praktisch zu verwenden!
class Program { static void Main(string[] args) { int Parame = 100;//当做参数 int Result = 0;//当做返回值 //匿名方法 ThreadStart threadStart = new ThreadStart(delegate() { Random ra = new Random();//随机数对象 Thread.Sleep(ra.Next(10, 100));//随机休眠一段时间 Console.WriteLine(Parame);//输出参数 Result = Parame * ra.Next(10, 100);//计算返回值 }); Thread thread = new Thread(threadStart); thread.Start();//多线程启动匿名方法 //等待线程结束 while (thread.ThreadState != ThreadState.Stopped) { Thread.Sleep(10); } Console.WriteLine(Result);//打印返回值 Console.Read(); } }
(5) Verwenden Sie die Delegation, um Multithreading (Multithreading im Detail) zu aktivieren
1. Verwenden Sie die BeginInvoke- und EndInvoke-Methoden des Delegaten (Delegate), um Threads zu betreiben
BeginInvoke-Methode Sie können Threads verwenden, um die Methode, auf die der Delegat zeigt, asynchron auszuführen. Rufen Sie dann den Rückgabewert der Methode über die EndInvoke-Methode ab (der Rückgabewert der EndInvoke-Methode ist der Rückgabewert der aufgerufenen Methode) oder stellen Sie fest, dass die Methode erfolgreich aufgerufen wurde.
class Program { private delegate int NewTaskDelegate(int ms); private static int newTask(int ms) { Console.WriteLine("任务开始"); Thread.Sleep(ms); Random random = new Random(); int n = random.Next(10000); Console.WriteLine("任务完成"); return n; } static void Main(string[] args) { NewTaskDelegate task = newTask; IAsyncResult asyncResult = task.BeginInvoke(2000, null, null); //EndInvoke方法将被阻塞2秒 int result = task.EndInvoke(asyncResult); Console.WriteLine(result); Console.Read(); } }
2. Verwenden Sie die Eigenschaft IAsyncResult.IsCompleted, um zu bestimmen, ob der asynchrone Aufruf abgeschlossen ist
class Program { private delegate int NewTaskDelegate(int ms); private static int newTask(int ms) { Console.WriteLine("任务开始"); Thread.Sleep(ms); Random random = new Random(); int n = random.Next(10000); Console.WriteLine("任务完成"); return n; } static void Main(string[] args) { NewTaskDelegate task = newTask; IAsyncResult asyncResult = task.BeginInvoke(2000, null, null); //等待异步执行完成 while (!asyncResult.IsCompleted) { Console.Write("*"); Thread.Sleep(100); } // 由于异步调用已经完成,因此, EndInvoke会立刻返回结果 int result = task.EndInvoke(asyncResult); Console.WriteLine(result); Console.Read(); } }
3. Verwenden Sie die WaitOne-Methode, um auf den Abschluss der asynchronen Methodenausführung zu warten
Der One-Parameter von WaitOne gibt die Anzahl der zu wartenden Millisekunden an. Innerhalb der angegebenen Zeit wartet die WaitOne-Methode, bis der asynchrone Aufruf abgeschlossen ist und eine Benachrichtigung ausgegeben wird, und die WaitOne-Methode gibt true zurück. Wenn der asynchrone Aufruf nach der angegebenen Zeit nicht abgeschlossen wird, gibt die WaitOne-Methode „false“ zurück. Wenn die angegebene Zeit 0 ist, bedeutet dies, dass nicht gewartet wird. Wenn sie -1 ist, bedeutet dies, dass ewig gewartet wird, bis der asynchrone Aufruf abgeschlossen ist.
class Program { private delegate int NewTaskDelegate(int ms); private static int newTask(int ms) { Console.WriteLine("任务开始"); Thread.Sleep(ms); Random random = new Random(); int n = random.Next(10000); Console.WriteLine("任务完成"); return n; } static void Main(string[] args) { NewTaskDelegate task = newTask; IAsyncResult asyncResult = task.BeginInvoke(2000, null, null); //等待异步执行完成 while (!asyncResult.AsyncWaitHandle.WaitOne(100, false)) { Console.Write("*"); } int result = task.EndInvoke(asyncResult); Console.WriteLine(result); Console.Read(); } }
4. Verwenden Sie die Callback-Methode, um Ergebnisse zurückzugeben
Es ist zu beachten, dass „my.BeginInvoke(3,300, MethodCompleted, my)“ die Parameterübergabemethode der BeginInvoke-Methode ist :
Der erste Teil (3.300) ist der Parameter seines Delegaten selbst.
Der vorletzte Parameter (MethodCompleted) ist der Delegate der Callback-Methode. Dieser Delegat hat einen Parameter vom Typ IAsyncResult Ruft automatisch die MethodCompleted-Methode auf.
Der letzte Parameter (my) muss einen Wert an die MethodCompleted-Methode übergeben. Im Allgemeinen kann der Delegat der aufgerufenen Methode mit der Eigenschaft IAsyncResult.AsyncState abgerufen werden.
class Program { private delegate int MyMethod(int second, int millisecond); //线程执行方法 private static int method(int second, int millisecond) { Console.WriteLine("线程休眠" + (second * 1000 + millisecond) + "毫秒"); Thread.Sleep(second * 1000 + millisecond); Random random = new Random(); return random.Next(10000); } //回调方法 private static void MethodCompleted(IAsyncResult asyncResult) { if (asyncResult == null || asyncResult.AsyncState == null) { Console.WriteLine("回调失败!!!"); return; } int result = (asyncResult.AsyncState as MyMethod).EndInvoke(asyncResult); Console.WriteLine("任务完成,结果:" + result); } static void Main(string[] args) { MyMethod my = method; IAsyncResult asyncResult = my.BeginInvoke(3,300, MethodCompleted, my); Console.WriteLine("任务开始"); Console.Read(); } }
5. BeginXXX- und EndXXX-Methoden anderer Komponenten
Es gibt auch ähnliche Methoden wie BeginInvoke und EndInvoke in anderen .net-Komponenten, wie z. B. BeginGetResponse und EndGetResponse von System.Net. HttpWebRequest-Klassenmethode. Seine Verwendung ähnelt den BeginInvoke- und EndInvoke-Methoden des Delegate-Typs, zum Beispiel:
class Program { //回调函数 private static void requestCompleted(IAsyncResult asyncResult) { if (asyncResult == null || asyncResult.AsyncState==null) { Console.WriteLine("回调失败"); return; } HttpWebRequest hwr = asyncResult.AsyncState as HttpWebRequest; HttpWebResponse response = (HttpWebResponse)hwr.EndGetResponse(asyncResult); StreamReader sr = new StreamReader(response.GetResponseStream()); string str = sr.ReadToEnd(); Console.WriteLine("返回流长度:"+str.Length); } static void Main(string[] args) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.baidu.com"); //异步请求 IAsyncResult asyncResult = request.BeginGetResponse(requestCompleted, request); Console.WriteLine("任务开始"); Console.Read(); } }