时间:2021-07-01 10:21:17 帮助过:20人阅读
- <br>public class EAP_Typical <br>{ <br>public static void AsyncRun() <br>{ <br>Utility.Log("AsyncRun:start"); <br>//测试网址 <br>string url = http://sports.163.com/nba/; <br>using (WebClient webClient = new WebClient()) <br>{ <br>//获取完成情况 <br>webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted); <br>webClient.DownloadStringAsync(new Uri(url)); <br>Utility.Log("AsyncRun:download_start"); <br>} <br>} <br>static void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) <br>{ <br>string log = "AsyncRun:download_completed"; <br>//获取返回结果 <br>log += "|result_size=" + Utility.GetStrLen(e.Result); <br>Utility.Log(log); <br>} <br>} <br> <br><strong>捕获异常</strong> <br>异常信息一般在Completed的事件参数中传递的。紧接上面的例子,如果需要获取返回的异常信息,则需要改写一下DownloadStringComleted的方法。 <br><span><u></u></span> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>static void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) <br>{ <br>string log = "AsyncRun:download_completed"; <br>if (e.Error != null) //可见,在事件的参数传输异常信息 <br>{ <br>//出现异常,就记录异常 <br>log += "|error=" + e.Error.Message; <br>} <br>else <br>{ <br>//没有出现异常,则记录结果 <br>log += "|result_size=" + Utility.GetStrLen(e.Result); <br>} <br>Utility.Log(log); <br>} <br> <br><strong>状态</strong> <br>EAP本身并没有维护状态,如果需要的话,应该设置不同的时间响应不同的状态改变; <br>假设刚才的DownloadStringAsync,需要增加多几个状态值,可以考虑增加多几个事件。 <br>如 <br>Event DownloadStringStarted(响应下载刚开始) <br>Event DownloadStringPending(响应下载阻塞中) <br>Event DownloadStringCancel(响应下载取消时) <br>等等。 <br><br><strong>取消操作</strong> <br>按命名规范,如果操作对应有“[方法名称]AsyncCancel”(或只是 CancelAsync)方法,则支持取消操作。 <br>取消的状态捕获,还是以刚才的下载Url</li></ol></pre>输出html为例,还是在DownloadStringCompleted 获取取消与否的状态。DownloadStringCompletedEventArgs. Cancelled <br>注意的是,如果用户执行了CancelAsync后,在DownloadStringCompletedEventArgs.Error就会获取到对应的异常,此时不要再取DownloadStringCompletedEventArgs.Result。 <br><br><strong>进度报告</strong> <br>EAP没有硬性规定说要支持进度报告,但可以很顺其自然地通过时间响应进度变化。 <br>以当前例子,WebClient 就提供了DownloadProgressChanged 做进度变化的响应事件。 <br><br><strong>APM</strong> <br><strong>命名、参数、返回值</strong> <br>APM的编程模式的代码命名有以下特点: <br>•使用 IAsyncResult 设计模式的异步操作是通过名为[Begin操作名称] 和 [End操作名称] 的两个方法来实现的,这两个方法分别开始和结束异步操作 操作名称。 例如,FileStream 类提供 BeginRead 和 EndRead 方法来从文件异步读取字节。 这两个方法实现了 Read 方法的异步版本。 <br>•在调用 [Begin操作名称] 后,应用程序可以继续在调用线程上执行指令,同时异步操作在另一个线程上执行。 每次调用 [Begin操作名称] 时,应用程序还应调用 [End操作名称] 来获取操作的结果。<br><br><strong>典型应用</strong> <br>以请求一个Url为例 <br><span><u></u></span> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>using System; <br>using System.Collections.Generic; <br>using System.Linq; <br>using System.Text; <br>using System.Net; <br>using System.IO; <br>namespace AsyncTest1.APM <br>{ <br>public class APMTestRun1 <br>{ <br>public static void AsyncRun() <br>{ <br>Utility.Log("APMAsyncRun:start"); <br>//测试网址 <br>string url = "http://sports.163.com/nba/"; <br>HttpWebRequest webRequest = HttpWebRequest.Create(url) as HttpWebRequest; <br>webRequest.BeginGetResponse(Callback, webRequest); <br>Utility.Log("AsyncRun:download_start"); <br>} <br>private static void Callback(IAsyncResult ar) <br>{ <br>var source = ar.AsyncState as HttpWebRequest; <br>var response = source.EndGetResponse(ar); <br>using (var stream = response.GetResponseStream()) <br>{ <br>using (var reader = new StreamReader(stream)) <br>{ <br>string content = reader.ReadToEnd(); <br>Utility.Log("AsyncRun:result_size=" + Utility.GetStrLen(content)); <br>} <br>} <br>} <br>} <br>} <br> <br>委托的异步调用也用的是APM模式,这个方式的强大之处,在于可以使任何方法编程异步调用。 <br><span><u></u></span> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>/// <summary> <br>/// 一个耗时的方法 <br>/// </summary> <br>private static void CaluateManyNumber() { <br>for (int i = 0; i < 10; i++) <br>{ <br>Thread.Sleep(100); <br>Console.WriteLine("loop==>"+i.ToString()); <br>} <br>} <br>/// <summary> <br>/// 委托,让耗时方法可以异步执行 <br>/// </summary> <br>public static void AsyncDelegate() { <br>//委托简单的包装了一下方法 <br>Action action = CaluateManyNumber; <br>action.BeginInvoke(DelegateCallback, null); <br>Console.WriteLine("action begin"); <br>} <br>/// <summary> <br>/// 异步回调 <br>/// </summary> <br>/// <param name="ar"></param> <br>private static void DelegateCallback(IAsyncResult ar) { <br>AsyncResult asyncResult = ar as AsyncResult; <br>var delegateSource = asyncResult.AsyncDelegate as Action; <br>delegateSource.EndInvoke(ar); <br>Console.WriteLine("action end"); <br>} <br> <br><strong>捕获异常</strong> <br>异常信息要在[End操作名称]中获取。 <br><span><u></u></span> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>private static void Callback(IAsyncResult ar) <br>{ <br>var source = ar.AsyncState as HttpWebRequest; <br>WebResponse response = null; <br>try <br>{ <br>response = source.EndGetResponse(ar); <br>} <br>catch (Exception ex) { <br>Utility.Log("error:" + ex.Message); <br>response = null; <br>} <br>if (response != null) <br>{ <br>using (var stream = response.GetResponseStream()) <br>{ <br>using (var reader = new StreamReader(stream)) <br>{ <br>string content = reader.ReadToEnd(); <br>Utility.Log("AsyncRun:result_size=" + Utility.GetStrLen(content)); <br>} <br>} <br>} <br>} <br> <br><strong>状态和取消操作、进度报告</strong> <br>APM模式本身不支持状态多样化和取消操作、进度报告。</li><li> </li><li> </li></ol></pre></li></ol></pre></li></ol></pre>