ホームページ >バックエンド開発 >C#.Net チュートリアル >C# でマルチスレッドを使用するいくつかの方法の詳細な例
(1) パラメータを渡したりパラメータを返したりする必要はありません。
ThreadStart はデリゲートであり、パラメータも戻り値もありません。
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) 単一のパラメーターを渡す必要があります
ParameterThreadStart デリゲートは void ParameterizedThreadStart(object state) として定義されており、パラメーターは 1 つありますが、戻り値はありません。
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) 特別なスレッドクラスを使用する(一般的に使用される)
スレッドクラスを使用すると、複数のパラメータと複数の戻り値を持つことができ、非常に柔軟です!
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) 匿名メソッドを使う(よく使われる)
匿名メソッドを使ってスレッドを起動すると、複数のパラメータや戻り値を持たせることができ、とても便利です!
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) デリゲートを使用してマルチスレッドを有効にする(マルチスレッドの詳細)
1. デリゲート(Delegate)のBeginInvokeメソッドとEndInvokeメソッドを使用してスレッドを操作します
BeginInvokeメソッドはスレッドを使用して非同期に実行できます。デリゲートが指すメソッドを実行します。次に、EndInvoke メソッドを通じてメソッドの戻り値を取得する (EndInvoke メソッドの戻り値は、呼び出されたメソッドの戻り値です)、またはメソッドが正常に呼び出されたことを確認します。
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. IAsyncResult.IsCompleted プロパティを使用して、非同期呼び出しが完了したかどうかを確認します
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. WaitOne メソッドを使用して、非同期メソッドの実行の完了を待機します
WaitOne の最初のパラメーターはミリ秒数を表します。指定された時間内に待機します。WaitOne メソッドは、非同期呼び出しが完了して通知が発行されるまで待機し、WaitOne メソッドは true を返します。指定した時間を待っても非同期呼び出しが完了しない場合、WaitOne メソッドは false を返します。指定した時間が 0 の場合は、待機しないことを意味します。-1 の場合は、非同期呼び出しが完了するまで待機することを意味します。
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. コールバック メソッドを使用して結果を返します
BeginInvoke メソッドのパラメータ渡しメソッドである「my.BeginInvoke(3,300, MethodCompleted, my)」に注意してください:
最初の部分 (3,300)デリゲート自体のパラメータです。
最後から 2 番目のパラメーター (MethodCompleted) は、コールバック メソッドのデリゲートです。このデリゲートには戻り値がなく、メソッド メソッドが実行されると、システムが自動的に呼び出します。 MethodCompleted メソッド。
最後のパラメーター (my) は、MethodCompleted メソッドに何らかの値を渡す必要があります。通常、この値は、IAsyncResult.AsyncState プロパティを使用して取得できます。
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 メソッドと EndXXX メソッド
System.Net.HttpWebRequest クラスの BeginGetResponse メソッドと EndGetResponse メソッドなど、他の .net コンポーネントの BeginInvoke と EndInvoke に似たメソッドもあります。その使用法は、デリゲート型の BeginInvoke メソッドと EndInvoke メソッドに似ています。例:
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(); } }