異步編程是受公共語(yǔ)言運(yùn)行庫(kù)的許多領(lǐng)域(如遠(yuǎn)程處理、asp.net 和 windows 窗體)支持的功能。異步編程是 .net framework 中的核心概念。使用 .net 異步編程,在程序繼續(xù)執(zhí)行的同時(shí)對(duì) .net 類(lèi)方法進(jìn)行調(diào)用,直到進(jìn)行指定的回調(diào)為止;或者如果沒(méi)有提供回調(diào),則直到對(duì)調(diào)用的阻塞、輪詢(xún)或等待完成為止。
異步編程是由 .net framework 的許多區(qū)域支持的功能,這些區(qū)域包括:
文件 io、流 io、套接字 io
網(wǎng)絡(luò):http、tcp
遠(yuǎn)程處理信道(http、tcp)和代理
使用 asp.net 創(chuàng)建的 xml web services
asp.net web 窗體
使用 messagequeue 類(lèi)的消息隊(duì)列
異步委托
.net framework 允許異步調(diào)用任何方法。定義與需要調(diào)用的方法具有相同簽名的委托;公共語(yǔ)言運(yùn)行庫(kù)將自動(dòng)為該委托定義具有適當(dāng)簽名的 begininvoke 和 endinvoke 方法。
begininvoke 方法用于啟動(dòng)異步調(diào)用。它與需要異步執(zhí)行的方法具有相同的參數(shù),只不過(guò)還有兩個(gè)額外的參數(shù)(將在稍后描述)。begininvoke 立即返回,不等待異步調(diào)用完成。begininvoke 返回 iasyncresult,可用于監(jiān)視調(diào)用進(jìn)度。
endinvoke 方法用于檢索異步調(diào)用結(jié)果。調(diào)用 begininvoke 后可隨時(shí)調(diào)用 endinvoke 方法;如果異步調(diào)用未完成,endinvoke 將一直阻塞到異步調(diào)用完成。endinvoke 的參數(shù)包括需要異步執(zhí)行的方法的 out 和 ref 參數(shù)以及由 begininvoke 返回的 iasyncresult。
調(diào)用了 begininvoke 后,可以:
進(jìn)行某些操作,然后調(diào)用 endinvoke 一直阻塞到調(diào)用完成。
使用 iasyncresult.asyncwaithandle 獲取 waithandle,使用它的 waitone 方法將執(zhí)行一直阻塞到發(fā)出 waithandle 信號(hào),然后調(diào)用 endinvoke。
輪詢(xún)由 begininvoke 返回的 iasyncresult,確定異步調(diào)用何時(shí)完成,然后調(diào)用 endinvoke。
將用于回調(diào)方法的委托傳遞給 begininvoke。該方法在異步調(diào)用完成后在 threadpool 線程上執(zhí)行,它可以調(diào)用 endinvoke。
下面是一個(gè)使用委托調(diào)用異步方法的例子。實(shí)例中首先定義了一個(gè)adddelegate類(lèi)型委托add,并將方法add綁定到委托實(shí)例上。然后定義了iasyncresult接口類(lèi)型實(shí)例iar并調(diào)用委托add的begininvoke方法用于啟動(dòng)異步調(diào)用。由于異步調(diào)用完成時(shí)會(huì)發(fā)出 waithandle 信號(hào),因此可以通過(guò)iar.asyncwaithandle.waitone();來(lái)等待它,在這期間主程序可以執(zhí)行一些其他的任務(wù)以達(dá)到程序異步執(zhí)行的效果。最后調(diào)用endinvoke 方法用于檢索異步調(diào)用結(jié)果。值得注意的是如果異步調(diào)用未完成,endinvoke 將一直阻塞到異步調(diào)用完成。
using system;
using system.threading;
//使用委托調(diào)用異步方法的例子
namespace delegatecallasynchronousmethods
...{
class asyncdelegatesblocked
...{
public static int add(int op1, int op2, out int result)
...{
thread.sleep(3000); // simulating work
return (result = op1 + op2);
}
public delegate int adddelegate(int op1, int op2,
out int result);//聲明adddelegate委托
static void main()
...{
int result;
/**//*定義一個(gè)adddelegate類(lèi)型委托add,將方法add綁定到委托實(shí)例上*/
adddelegate add = new adddelegate(add);
console.writeline("[main] invoking the asynchronous " +
"add method");
/**//*begininvoke 方法用于啟動(dòng)異步調(diào)用。它與您需要異步執(zhí)行的方法具有相同的參數(shù),還有兩個(gè)額外的參數(shù)
*begininvoke 立即返回,不等待異步調(diào)用完成。begininvoke 返回 iasyncresult,可用于監(jiān)視調(diào)用進(jìn)度。*/
//定義iasyncresult接口類(lèi)型實(shí)例iar
//6, 42, out result為異步執(zhí)行的方法的參數(shù)列表
iasyncresult iar = add.begininvoke(6, 42, out result,
null, null);
// here we're simulating doing some work before
// blocking on the add method's completion.
console.write("[main] doing other work");
for (int i = 0; i < 10; i++)
...{
thread.sleep(200);
console.write(".");
}
console.writeline(" [main] waiting for add to finish");
/**//*使用 iasyncresult.asyncwaithandle 獲取 waithandle,
* 使用它的 waitone 方法將執(zhí)行一直阻塞到發(fā)出 waithandle 信號(hào),然后調(diào)用 endinvoke。
* 注意:異步調(diào)用完成時(shí)會(huì)發(fā)出 waithandle 信號(hào),可以通過(guò)waitone 來(lái)等待它*/
iar.asyncwaithandle.waitone();
console.writeline("[main] add finished, cleaning up");
/**//*endinvoke 方法用于檢索異步調(diào)用結(jié)果。調(diào)用 begininvoke 后可隨時(shí)調(diào)用 endinvoke 方法;
* 如果異步調(diào)用未完成,endinvoke 將一直阻塞到異步調(diào)用完成。
* endinvoke 的參數(shù)包括所需要異步執(zhí)行的方法的 out 和 ref 參數(shù)以及由 begininvoke 返回的 iasyncresult。*/
add.endinvoke(out result, iar);
console.writeline("[main] the result is {0}", result);
console.readline();
}
};
}
新聞熱點(diǎn)
疑難解答
圖片精選