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); }
使用事件异步计算:
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 }