首頁 >後端開發 >C#.Net教程 >c#使用多執行緒的幾種方式範例詳解

c#使用多執行緒的幾種方式範例詳解

高洛峰
高洛峰原創
2016-12-12 14:46:101556瀏覽

(1)不需要傳遞參數,也不需要回傳參數

ThreadStart是一個委託,這個委託的定義為void 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),有一個參數但沒有回傳值。

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、使用回呼方式回傳結果

要注意的是“my.BeginInvoke(3,300, MethodCompleted, my)”,BeginInvoke方法的參數傳遞方式:

前面一部分(3,300)是其委託本身的參數。

倒數第二個參數(MethodCompleted)是回呼方法委託類型,他是回呼方法的委託,此委託沒有回傳值,有一個IAsyncResult類型的參數,當method方法執行完後,系統會自動呼叫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方法

在其他的.net元件中也有類似BeginInvoke和EndInvoke的方法,如System.Net.HttpWebRequest類別的BeginGetResponse和EndGetResponse方法。其使用方法類似委託類型的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();
}
}


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn