佳木斯湛栽影视文化发展公司

主頁 > 知識(shí)庫 > .NET中的異步編程-EAP/APM使用方法及案例介紹

.NET中的異步編程-EAP/APM使用方法及案例介紹

熱門標(biāo)簽:銀行業(yè)務(wù) Linux服務(wù)器 阿里云 電子圍欄 科大訊飛語音識(shí)別系統(tǒng) 團(tuán)購網(wǎng)站 服務(wù)器配置 Mysql連接數(shù)設(shè)置
從.NET 4.5開始,支持的三種異步編程模式
•基于事件的異步編程設(shè)計(jì)模式 (EAP,Event-based Asynchronous Pattern)
•異步編程模型(APM,Asynchronous Programming Model)
•基于任務(wù)的編程模型(TAP,Task-based Asynchronous Pattern)
基于任務(wù)的異步模式 (TAP) 是基于 System.Threading.Tasks 命名空間的 Task 和 TaskTResult>,用于表示任意異步操作。 TAP 是新開發(fā)的建議異步設(shè)計(jì)模式,之后再討論。

先總結(jié)一下舊有的2種模式:EAP、APM
。
從以下幾個(gè)方面,看這2種異步編程方式的異同:
•命名、參數(shù)、返回值
•典型應(yīng)用
•捕獲異常
•狀態(tài)
•取消操作
•進(jìn)度報(bào)告

EAP
命名、參數(shù)、返回值
EAP的編程模式的代碼命名有以下特點(diǎn):
•將有一個(gè)或多個(gè)名為 “[方法名稱]Async” 的方法。這些方法可能會(huì)創(chuàng)建同步版本的鏡像,這些同步版本會(huì)在當(dāng)前線程上執(zhí)行相同的操作。
•該類還可能有一個(gè) “[方法名稱]Completed” 事件,監(jiān)聽異步方法的結(jié)果。
•它可能會(huì)有一個(gè) “[方法名稱]AsyncCancel”(或只是 CancelAsync)方法,用于取消正在進(jìn)行的異步操作。
參數(shù)和返回值都沒有特殊規(guī)定,按照業(yè)務(wù)需求而定

典型應(yīng)用
以請(qǐng)求一個(gè)Url為例
復(fù)制代碼 代碼如下:

public class EAP_Typical
{
public static void AsyncRun()
{
Utility.Log("AsyncRun:start");
//測試網(wǎng)址
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";
//獲取返回結(jié)果
log += "|result_size=" + Utility.GetStrLen(e.Result);
Utility.Log(log);
}
}

捕獲異常
異常信息一般在Completed的事件參數(shù)中傳遞的。緊接上面的例子,如果需要獲取返回的異常信息,則需要改寫一下DownloadStringComleted的方法。
復(fù)制代碼 代碼如下:

static void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string log = "AsyncRun:download_completed";
if (e.Error != null) //可見,在事件的參數(shù)傳輸異常信息
{
//出現(xiàn)異常,就記錄異常
log += "|error=" + e.Error.Message;
}
else
{
//沒有出現(xiàn)異常,則記錄結(jié)果
log += "|result_size=" + Utility.GetStrLen(e.Result);
}
Utility.Log(log);
}

狀態(tài)
EAP本身并沒有維護(hù)狀態(tài),如果需要的話,應(yīng)該設(shè)置不同的時(shí)間響應(yīng)不同的狀態(tài)改變;
假設(shè)剛才的DownloadStringAsync,需要增加多幾個(gè)狀態(tài)值,可以考慮增加多幾個(gè)事件。

Event DownloadStringStarted(響應(yīng)下載剛開始)
Event DownloadStringPending(響應(yīng)下載阻塞中)
Event DownloadStringCancel(響應(yīng)下載取消時(shí))
等等。

取消操作
按命名規(guī)范,如果操作對(duì)應(yīng)有“[方法名稱]AsyncCancel”(或只是 CancelAsync)方法,則支持取消操作。
取消的狀態(tài)捕獲,還是以剛才的下載Url輸出html為例,還是在DownloadStringCompleted 獲取取消與否的狀態(tài)。DownloadStringCompletedEventArgs. Cancelled
注意的是,如果用戶執(zhí)行了CancelAsync后,在DownloadStringCompletedEventArgs.Error就會(huì)獲取到對(duì)應(yīng)的異常,此時(shí)不要再取DownloadStringCompletedEventArgs.Result。

進(jìn)度報(bào)告
EAP沒有硬性規(guī)定說要支持進(jìn)度報(bào)告,但可以很順其自然地通過時(shí)間響應(yīng)進(jìn)度變化。
以當(dāng)前例子,WebClient 就提供了DownloadProgressChanged 做進(jìn)度變化的響應(yīng)事件。

APM
命名、參數(shù)、返回值
APM的編程模式的代碼命名有以下特點(diǎn):
•使用 IAsyncResult 設(shè)計(jì)模式的異步操作是通過名為[Begin操作名稱] 和 [End操作名稱] 的兩個(gè)方法來實(shí)現(xiàn)的,這兩個(gè)方法分別開始和結(jié)束異步操作 操作名稱。 例如,F(xiàn)ileStream 類提供 BeginRead 和 EndRead 方法來從文件異步讀取字節(jié)。 這兩個(gè)方法實(shí)現(xiàn)了 Read 方法的異步版本。
•在調(diào)用 [Begin操作名稱] 后,應(yīng)用程序可以繼續(xù)在調(diào)用線程上執(zhí)行指令,同時(shí)異步操作在另一個(gè)線程上執(zhí)行。 每次調(diào)用 [Begin操作名稱] 時(shí),應(yīng)用程序還應(yīng)調(diào)用 [End操作名稱] 來獲取操作的結(jié)果。

典型應(yīng)用
以請(qǐng)求一個(gè)Url為例
復(fù)制代碼 代碼如下:

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");
//測試網(wǎng)址
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));
}
}
}
}
}

委托的異步調(diào)用也用的是APM模式,這個(gè)方式的強(qiáng)大之處,在于可以使任何方法編程異步調(diào)用。
復(fù)制代碼 代碼如下:

/// summary>
/// 一個(gè)耗時(shí)的方法
/// /summary>
private static void CaluateManyNumber() {
for (int i = 0; i 10; i++)
{
Thread.Sleep(100);
Console.WriteLine("loop==>"+i.ToString());
}
}
/// summary>
/// 委托,讓耗時(shí)方法可以異步執(zhí)行
/// /summary>
public static void AsyncDelegate() {
//委托簡單的包裝了一下方法
Action action = CaluateManyNumber;
action.BeginInvoke(DelegateCallback, null);
Console.WriteLine("action begin");
}
/// summary>
/// 異步回調(diào)
/// /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操作名稱]中獲取。
復(fù)制代碼 代碼如下:

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));
}
}
}
}

狀態(tài)和取消操作、進(jìn)度報(bào)告
APM模式本身不支持狀態(tài)多樣化和取消操作、進(jìn)度報(bào)告。
您可能感興趣的文章:
  • 深入分析C#異步編程詳解
  • 高效的.Net UDP異步編程實(shí)現(xiàn)分析
  • .net4.5使用async和await異步編程實(shí)例

標(biāo)簽:棗莊 萍鄉(xiāng) 衢州 廣元 蚌埠 大理 衡水 江蘇

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《.NET中的異步編程-EAP/APM使用方法及案例介紹》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    郑州市| 南岸区| 昔阳县| 茶陵县| 上林县| 蓝山县| 丹寨县| 巨野县| 吉首市| 张家界市| 宜章县| 石城县| 米泉市| 新泰市| 潜山县| 曲沃县| 石阡县| 朝阳县| 宁阳县| 志丹县| 马公市| 曲沃县| 绩溪县| 舞钢市| 鹤峰县| 澄迈县| 淮北市| 台前县| 龙口市| 绍兴市| 东台市| 齐齐哈尔市| 沂源县| 门源| 丰都县| 盘山县| 高州市| 灵石县| 集安市| 遂平县| 申扎县|