APM(=Asynchronous PRogramming Model(=異步編程模型))
使用 IAsyncResult 設計模式的異步操作是通過名為 Begin操作名稱 和 End操作名稱 的兩個方法來實現的,這兩個方法分別開始和結束異步操作 操作名稱。 例如,FileStream 類提供 BeginRead 和 EndRead 方法來從文件異步讀取字節。 這兩個方法實現了 Read 方法的異步版本。 在調用 Begin操作名稱 后,應用程序可以繼續在調用線程上執行指令,同時異步操作在另一個線程上執行。 每次調用 Begin操作名稱 時,應用程序還應調用 End操作名稱 來獲取操作的結果。 ——MSDN


BeginInvoke 方法啟動異步調用。 該方法與您需要異步執行的方法具有相同的參數,還有另外兩個可選參數。第一個參數是一個 AsyncCallback 委托,該委托引用在異步調用完成時要調用的方法。 第二個參數是一個用戶定義的對象,該對象將信息傳遞到回調方法。BeginInvoke 立即返回,不等待異步調用完成。 BeginInvoke 返回一個 IAsyncResult,后者可用于監視異步調用的進度。
EndInvoke 方法檢索異步調用的結果。 在調用 BeginInvoke 之后隨時可以調用該方法。 如果異步調用尚未完成,則 EndInvoke 會一直阻止調用線程,直到異步調用完成。 EndInvoke 的參數包括您需要異步執行的方法的 out 和 ref 參數(在 Visual Basic 中為 <Out> ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。
無論您使用何種方法,都要調用 EndInvoke 來完成異步調用。
異步執行方法的最簡單方式是通過調用委托的 BeginInvoke 方法來開始執行方法,在主線程上執行一些操作,然后調用委托的 EndInvoke 方法。 EndInvoke 可能會阻止調用線程,因為該方法直到異步調用完成后才返回。 這種方式非常適合執行文件或網絡操作。因為 EndInvoke 可能會阻塞,所以不應從服務于用戶界面的線程調用該方法。
——MSDN
1.普通示例
using System;using System.Runtime.Remoting.Messaging;namespace Consoleapplication18{ class Program { static void Main(string[] args) { Func<string, string> _processTimeFunc = new Func<string, string>((string arg) => { return string.Format("{0} {1}", arg, DateTime.Now); }); _processTimeFunc.BeginInvoke("Beijing ", InvokeTimeFuncEnd, _processTimeFunc);//將委托作為參數傳遞 _processTimeFunc.BeginInvoke("Shanghai ", InvokeTimeFuncEnd2, null);//參數為空 Console.ReadLine(); } private static void InvokeTimeFuncEnd2(IAsyncResult ar) { AsyncResult _asyncResult = (AsyncResult)ar; Func<string, string> _processTimeFunc = (Func<string, string>)_asyncResult.AsyncDelegate;//獲取委托 Console.WriteLine(_processTimeFunc.EndInvoke(ar)); } private static void InvokeTimeFuncEnd(IAsyncResult ar) { Func<string, string> _processTimeFunc = (Func<string, string>)ar.AsyncState; Console.WriteLine(_processTimeFunc.EndInvoke(ar)); } }}代碼效果

2.IsCompleted使用示例
using System;namespace ConsoleApplication18{ class Program { static void Main(string[] args) { Func<string, string> _processTimeFunc = new Func<string, string>((string arg) => { return string.Format("{0} {1}", arg, DateTime.Now); }); IAsyncResult _result = _processTimeFunc.BeginInvoke("Beijing ", null, null); while (!_result.IsCompleted) { Console.Write("....."); } Console.WriteLine("/r/n" + _processTimeFunc.EndInvoke(_result)); Console.ReadLine(); } }}
代碼效果

3.超時設置
using System;using System.Threading;namespace ConsoleApplication18{ class Program { static void Main(string[] args) { Func<string, string> _processTimeFunc = new Func<string, string>((string arg) => { Thread.Sleep(6000); return string.Format("{0} {1}", arg, DateTime.Now); }); IAsyncResult _result = _processTimeFunc.BeginInvoke("Beijing ", null, null); if (_result.AsyncWaitHandle.WaitOne(5000, true)) Console.WriteLine("/r/n" + _processTimeFunc.EndInvoke(_result)); else Console.WriteLine("執行超時..."); Console.ReadLine(); } }}代碼效果

新聞熱點
疑難解答