IAsyncResult是接口:
IAsyncResult 異步設計模式通過名為 BeginOperationName 和 EndOperationName 的兩個方法來實現原同步方法的異步調用,如 FileStream 類提供了 BeginRead 和 EndRead 方法來從文件異步讀取字節,它們是 Read 方法的異步版本
Begin 方法包含同步方法簽名中的任何參數,此外還包含另外兩個參數:一個AsyncCallback 委托和一個用戶定義的狀態對象。委托用來調用回調方法,狀態對象是用來向回調方法傳遞狀態信息。該方法返回一個實現 IAsyncResult 接口的對象
End 方法用於結束異步操作並返回結果,因此包含同步方法簽名中的 ref 和 out 參數,返回值類型也與同步方法相同。該方法還包括一個 IAsyncResult 參數,用於獲取異步操作是否完成的信息,當然在使用時就必須傳入對應的 Begin 方法返回的對象實例
開始異步操作後如果要阻止應用程序,可以直接調用 End 方法,這會阻止應用程序直到異步操作完成後再繼續執行。也可以使用 IAsyncResult 的 AsyncWaitHandle 屬性,調用其中的WaitOne等方法來阻塞線程。這兩種方法的區別不大,只是前者必須一直等待而後者可以設置等待超時
如果不阻止應用程序,則可以通過輪循 IAsyncResult 的 IsCompleted 狀態來判斷操作是否完成,或使用 AsyncCallback 委托來結束異步操作。AsyncCallback 委托包含一個 IAsyncResult 的簽名,回調方法內部再調用 End 方法來獲取操作執行結果
//C#異步編程模式IAsyncResult之IAsyncResult 接口 public interface IAsyncResult { object AsyncState { get; } WaitHandle AsyncWaitHandle { get; } bool CompletedSynchronously { get; } bool IsCompleted { get; } }
以上是IAsyncResult 接口的屬性。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Runtime.Remoting.Messaging; namespace ConsoleTest { public delegate int AddHandler(int a, int b); public class 加法類 { public static int Add(int a, int b) { Console.WriteLine("開始計算:" + a + "+" + b); Thread.Sleep(3000); //模擬該方法運行三秒 Console.WriteLine("計算完成!"); return a + b; } } #region public class 同步調用 { static void Main() { Console.WriteLine("===== 同步調用 SyncInvokeTest ====="); AddHandler handler = new AddHandler(加法類.Add); int result = handler.Invoke(1, 2); Console.WriteLine("繼續做別的事情。。。"); Console.WriteLine(result); Console.ReadKey(); } } #endregion }
/*運行結果:
===== 同步調用 SyncInvokeTest =====
開始計算:1+2
計算完成!
繼續做別的事情。。。
3
*/
public delegate int AddHandler(int a, int b); public class 加法類 { public static int Add(int a, int b) { Console.WriteLine("開始計算:" + a + "+" + b); Thread.Sleep(3000); //模擬該方法運行三秒 Console.WriteLine("計算完成!"); return a + b; } } #region 異步調用 public class 異步調用 { static void Main() { Console.WriteLine("===== 異步調用 AsyncInvokeTest ====="); AddHandler handler = new AddHandler(加法類.Add); //IAsyncResult: 異步操作接口(interface) //BeginInvoke: 委托(delegate)的一個異步方法的開始 IAsyncResult result = handler.BeginInvoke(1, 2, null, null); //如果在2秒內完成計算 if (result.AsyncWaitHandle.WaitOne(2000, true)) { Console.WriteLine(handler.EndInvoke(result)); Console.WriteLine(result); } Console.WriteLine("繼續做別的事情。。。"); //異步操作返回 Console.WriteLine(handler.EndInvoke(result)); Console.ReadKey(); }
運行結果:
異步回掉:
public delegate int AddHandler(int a, int b); public class 加法類 { public static int Add(int a, int b) { Console.WriteLine("開始計算:" + a + "+" + b); Thread.Sleep(3000); //模擬該方法運行三秒 Console.WriteLine("計算完成!"); return a + b; } } #region 異步回掉函數 public class 異步回調 { static void Main() { Console.WriteLine("===== 異步回調 AsyncInvokeTest ====="); AddHandler handler = new AddHandler(加法類.Add); //異步操作接口(注意BeginInvoke方法的不同!) IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback(回調函數),"AsycState:OK"); //IAsyncResult result1 = handler.BeginInvoke(3, 4, new AsyncCallback(CallBackFuncation), "異步回掉完成"); Console.WriteLine("繼續做別的事情。。。"); Console.ReadKey(); } static void 回調函數(IAsyncResult result) { //result 是“加法類.Add()方法”的返回值 //AsyncResult 是IAsyncResult接口的一個實現類,引用空間:System.Runtime.Remoting.Messaging //AsyncDelegate 屬性可以強制轉換為用戶定義的委托的實際類。 AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate; Console.WriteLine(handler.EndInvoke(result)); Console.WriteLine(result.AsyncState); }View Code
使用事件異步計算:
public class TestFun { //模擬一個耗時計算 static int LongTimeMethod() { int result = 0; //Thread. Sleep(3000); for (int i = 0; i <= 100; i++) { result += i; } return result; } static void Main() { //這裡用到的是.Net中定義好的委托來執行BeginInvoke Func<int> longTimeAction = new Func<int>(LongTimeMethod); IAsyncResult asynResult = longTimeAction.BeginInvoke(null, null); //WaitOne //這個對象有一個WaitOne方法,還能接受一個超時時間,它會等待這個超時時間指定的長度 Func<int> longTimeAction1 = new Func<int>(LongTimeMethod); IAsyncResult asynResult1 = longTimeAction1.BeginInvoke(null, null); //可以繼續處理別的事情 if (asynResult1.AsyncWaitHandle.WaitOne(10000, true))//判斷是不是結果為true,只等你10s { int result1 = longTimeAction1.EndInvoke(asynResult1); Console.WriteLine(result1); } }
運行結果:
public class TestFun { //模擬一個耗時計算 static int LongTimeMethod() { int result = 0; //Thread. Sleep(3000); for (int i = 0; i <= 100; i++) { result += i; } return result; } static void Main() { //這裡用到的是.Net中定義好的委托來執行BeginInvoke Func<int> longTimeAction = new Func<int>(LongTimeMethod); IAsyncResult asynResult = longTimeAction.BeginInvoke(null, null); //輪詢 while (!asynResult.IsCompleted) { //當不是true時,就執行這裡的代碼 Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("計算還未完成,等待中...."); Console.ForegroundColor = ConsoleColor.Yellow; for (int i = 1; i < 100; i++) { for (int j = i; j < 100; j++) { int a = i, b = j; Console.WriteLine("{0}*{1}={2}", a, b, a * b); } } Console.Clear(); } int result1 = longTimeAction.EndInvoke(asynResult);//當是true時,就將結果返回顯示 Console.WriteLine("計算的結果為:" + result1); Console.ReadLine(); }
運行結果:
完整代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Runtime.Remoting.Messaging; namespace ConsoleTest { public delegate int AddHandler(int a, int b); public class 加法類 { public static int Add(int a, int b) { Console.WriteLine("開始計算:" + a + "+" + b); Thread.Sleep(3000); //模擬該方法運行三秒 Console.WriteLine("計算完成!"); return a + b; } } public class TestFun { //模擬一個耗時計算 static int LongTimeMethod() { int result = 0; //Thread. Sleep(3000); for (int i = 0; i <= 100; i++) { result += i; } return result; } static void Main() { //這裡用到的是.Net中定義好的委托來執行BeginInvoke Func<int> longTimeAction = new Func<int>(LongTimeMethod); IAsyncResult asynResult = longTimeAction.BeginInvoke(null, null); ////WaitOne ////這個對象有一個WaitOne方法,還能接受一個超時時間,它會等待這個超時時間指定的長度 //Func<int> longTimeAction1 = new Func<int>(LongTimeMethod); //IAsyncResult asynResult1 = longTimeAction1.BeginInvoke(null, null); ////可以繼續處理別的事情 //if (asynResult1.AsyncWaitHandle.WaitOne(10000, true))//判斷是不是結果為true,只等你10s //{ // int result1 = longTimeAction1.EndInvoke(asynResult1); // Console.WriteLine(result1); //} //回調 Func<int> longTimeAction2 = new Func<int>(LongTimeMethod); //這裡使用了一個lambda表達式,省了不少力啊 IAsyncResult asynResult2 = longTimeAction.BeginInvoke((result) => { int ret = longTimeAction.EndInvoke(result); Console.WriteLine(ret); }, null); //輪詢 while (!asynResult.IsCompleted) { //當不是true時,就執行這裡的代碼 Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("計算還未完成,等待中...."); Console.ForegroundColor = ConsoleColor.Yellow; for (int i = 1; i < 100; i++) { for (int j = i; j < 100; j++) { int a = i, b = j; Console.WriteLine("{0}*{1}={2}", a, b, a * b); } } Console.Clear(); } int result1 = longTimeAction.EndInvoke(asynResult);//當是true時,就將結果返回顯示 Console.WriteLine("計算的結果為:" + result1); Console.ReadLine(); } } #region 直接調用 //public class 同步調用 //{ // static void Main() // { // Console.WriteLine("===== 同步調用 SyncInvokeTest ====="); // AddHandler handler = new AddHandler(加法類.Add); // int result = handler.Invoke(1, 2); // Console.WriteLine("繼續做別的事情。。。"); // Console.WriteLine(result); // Console.ReadKey(); // } // /*運行結果: // ===== 同步調用 SyncInvokeTest ===== // 開始計算:1+2 // 計算完成! // 繼續做別的事情。。。 // 3 */ //} #endregion #region 異步調用 //public class 異步調用 //{ // static void Main() // { // Console.WriteLine("===== 異步調用 AsyncInvokeTest ====="); // AddHandler handler = new AddHandler(加法類.Add); // //IAsyncResult: 異步操作接口(interface) // //BeginInvoke: 委托(delegate)的一個異步方法的開始 // IAsyncResult result = handler.BeginInvoke(1, 2, null, null); // //如果在2秒內完成計算 // if (result.AsyncWaitHandle.WaitOne(2000, true)) // { // Console.WriteLine(handler.EndInvoke(result)); // Console.WriteLine(result); // } // Console.WriteLine("繼續做別的事情。。。"); // //異步操作返回 // Console.WriteLine(handler.EndInvoke(result)); // Console.ReadKey(); // } // /*運行結果: // ===== 異步調用 AsyncInvokeTest ===== // 繼續做別的事情。。。 // 開始計算:1+2 // 計算完成! // 3 */ //} //#endregion //public class 異步回調 //{ // static void Main() // { // Console.WriteLine("===== 異步回調 AsyncInvokeTest ====="); // AddHandler handler = new AddHandler(加法類.Add); // //異步操作接口(注意BeginInvoke方法的不同!) // IAsyncResult result = handler.BeginInvoke(1, 2, new AsyncCallback(回調函數), "AsycState:OK"); // //IAsyncResult result1 = handler.BeginInvoke(3, 4, new AsyncCallback(CallBackFuncation), "異步回掉完成"); // Console.WriteLine("繼續做別的事情。。。"); // Console.ReadKey(); // } // static void 回調函數(IAsyncResult result) // { // //result 是“加法類.Add()方法”的返回值 // //AsyncResult 是IAsyncResult接口的一個實現類,引用空間:System.Runtime.Remoting.Messaging // //AsyncDelegate 屬性可以強制轉換為用戶定義的委托的實際類。 // AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate; // Console.WriteLine(handler.EndInvoke(result)); // Console.WriteLine(result.AsyncState); // } // /*運行結果: // ===== 異步回調 AsyncInvokeTest ===== // 開始計算:1+2 // 繼續做別的事情。。。 // 計算完成! // 3 // AsycState:OK // */ // static void CallBackFuncation(IAsyncResult result) // { // Console.WriteLine("這裡是回掉函數"); // AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate; // Console.WriteLine(handler.EndInvoke(result)); // Console.WriteLine(result.AsyncState); // } //} #endregion }View Code