标签:sum pen 建议 else back str apm error pac
从.NET 4.5开始,支持的三种异步编程模式:
基于任务的异步模式 (TAP) 是基于 System.Threading.Tasks 命名空间的 Task 和 Task<TResult>,用于表示任意异步操作。 TAP 是新开发的建议异步设计模式,之后再讨论。
先总结一下旧有的2种模式:EAP、APM。
从以下几个方面,看这2种异步编程方式的异同:
EAP的编程模式的代码命名有以下特点:
参数和返回值都没有特殊规定,按照业务需求而定
以请求一个Url为例
public class EAP_Typical { public static void AsyncRun() { Utility.Log("AsyncRun:start"); //测试网址 string url = http://sports.163.com/nba/; using (WebClient webClient = new WebClient()) { //获取完成情况 webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(new Uri(url)); Utility.Log("AsyncRun:download_start"); } } static void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { string log = "AsyncRun:download_completed"; //获取返回结果 log += "|result_size=" + Utility.GetStrLen(e.Result); Utility.Log(log); } }
异常信息一般在Completed的事件参数中传递的。紧接上面的例子,如果需要获取返回的异常信息,则需要改写一下DownloadStringComleted的方法。
static void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { string log = "AsyncRun:download_completed"; if (e.Error != null) //可见,在事件的参数传输异常信息 { //出现异常,就记录异常 log += "|error=" + e.Error.Message; } else { //没有出现异常,则记录结果 log += "|result_size=" + Utility.GetStrLen(e.Result); } Utility.Log(log); }
EAP本身并没有维护状态,如果需要的话,应该设置不同的时间响应不同的状态改变;
假设刚才的DownloadStringAsync,需要增加多几个状态值,可以考虑增加多几个事件。
如
Event DownloadStringStarted(响应下载刚开始)
Event DownloadStringPending(响应下载阻塞中)
Event DownloadStringCancel(响应下载取消时)
等等。
按命名规范,如果操作对应有“[方法名称]AsyncCancel”(或只是 CancelAsync)方法,则支持取消操作。
取消的状态捕获,还是以刚才的下载Url输出html为例,还是在DownloadStringCompleted 获取取消与否的状态。DownloadStringCompletedEventArgs. Cancelled
注意的是,如果用户执行了CancelAsync后,在DownloadStringCompletedEventArgs.Error就会获取到对应的异常,此时不要再取DownloadStringCompletedEventArgs.Result。
EAP没有硬性规定说要支持进度报告,但可以很顺其自然地通过时间响应进度变化。
以当前例子,WebClient 就提供了DownloadProgressChanged 做进度变化的响应事件。
APM的编程模式的代码命名有以下特点:
以请求一个Url为例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; namespace AsyncTest1.APM { public class APMTestRun1 { public static void AsyncRun() { Utility.Log("APMAsyncRun:start"); //测试网址 string url = "http://sports.163.com/nba/"; HttpWebRequest webRequest = HttpWebRequest.Create(url) as HttpWebRequest; webRequest.BeginGetResponse(Callback, webRequest); Utility.Log("AsyncRun:download_start"); } private static void Callback(IAsyncResult ar) { var source = ar.AsyncState as HttpWebRequest; var response = source.EndGetResponse(ar); using (var stream = response.GetResponseStream()) { using (var reader = new StreamReader(stream)) { string content = reader.ReadToEnd(); Utility.Log("AsyncRun:result_size=" + Utility.GetStrLen(content)); } } } } }
委托的异步调用也用的是APM模式,这个方式的强大之处,在于可以使任何方法编程异步调用。
/// <summary> /// 一个耗时的方法 /// </summary> private static void CaluateManyNumber() { for (int i = 0; i < 10; i++) { Thread.Sleep(100); Console.WriteLine("loop==>"+i.ToString()); } } /// <summary> /// 委托,让耗时方法可以异步执行 /// </summary> public static void AsyncDelegate() { //委托简单的包装了一下方法 Action action = CaluateManyNumber; action.BeginInvoke(DelegateCallback, null); Console.WriteLine("action begin"); } /// <summary> /// 异步回调 /// </summary> /// <param name="ar"></param> private static void DelegateCallback(IAsyncResult ar) { AsyncResult asyncResult = ar as AsyncResult; var delegateSource = asyncResult.AsyncDelegate as Action; delegateSource.EndInvoke(ar); Console.WriteLine("action end"); }
异常信息要在[End操作名称]中获取。
private static void Callback(IAsyncResult ar) { var source = ar.AsyncState as HttpWebRequest; WebResponse response = null; try { response = source.EndGetResponse(ar); } catch (Exception ex) { Utility.Log("error:" + ex.Message); response = null; } if (response != null) { using (var stream = response.GetResponseStream()) { using (var reader = new StreamReader(stream)) { string content = reader.ReadToEnd(); Utility.Log("AsyncRun:result_size=" + Utility.GetStrLen(content)); } } } }
APM模式本身不支持状态多样化和取消操作、进度报告。
标签:sum pen 建议 else back str apm error pac
原文地址:https://www.cnblogs.com/deepminer/p/9075921.html