ホームページ > バックエンド開発 > C#.Net チュートリアル > C# でマルチスレッドを使用するいくつかの方法の詳細な例

C# でマルチスレッドを使用するいくつかの方法の詳細な例

高洛峰
リリース: 2016-12-12 14:46:10
オリジナル
1559 人が閲覧しました

(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();
}
}
ログイン後にコピー


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート