C#使用多線程並發之異步委托IAsyncResult


使用委托開啟多線程(多線程深入)

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(); } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM