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(); } }}代码效果
新闻热点
疑难解答