好創(chuàng)意的設(shè)計(jì)網(wǎng)站最大免費(fèi)廣告發(fā)布平臺(tái)
.NET Framework允許異步調(diào)用任何方法。定義與需要調(diào)用的方法具有相同簽名的委托;公共語(yǔ)言運(yùn)行庫(kù)將自動(dòng)為該委托定義具有適當(dāng)簽名的 BeginInvoke 和 EndInvoke 方法。以下介紹C#中,通過(guò)BeginInvoke()和EndInvoke()來(lái)實(shí)現(xiàn)異步。
?
1、異步編程
調(diào)用BeginInvoke
可以執(zhí)行任務(wù),然后調(diào)用EndInvoke阻塞直到調(diào)用完成。使用IAsyncResult.AsyncWaitHandle
屬性獲取WaitHandle
,使用其WaitOne
方法阻止執(zhí)行,直到發(fā)出WaitHandle
信號(hào),然后調(diào)用EndInvoke
輪詢(xún)返回的IAsyncResultBeginInvoke
以確定異步調(diào)用何時(shí)完成,然后調(diào)用EndInvoke
。將回調(diào)方法的委托傳遞給BeginInvoke
。當(dāng)異步調(diào)用完成時(shí),該方法在ThreadPool
線(xiàn)程上執(zhí)行。回調(diào)方法調(diào)用EndInvoke
。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)用完成。
2、同步方法和異步方法區(qū)別
同步方法調(diào)用在程序繼續(xù)執(zhí)行之前,需要等待同步方法執(zhí)行完畢返回結(jié)果,異步方法則在被調(diào)用之后,立即返回以便程序在被調(diào)用方法完成其任務(wù)的同時(shí)執(zhí)行其它操作。
3、異步操作的優(yōu)缺點(diǎn)
異步操作無(wú)須額外的線(xiàn)程負(fù)擔(dān),并且使用回調(diào)的方式進(jìn)行處理,在設(shè)計(jì)良好的情況下,處理函數(shù)可以不必使用共享變量,即使無(wú)法完全不用,最起碼可以減少共享變量的數(shù)量,減少了死鎖的可能。當(dāng)然異步操作也并非完美。編寫(xiě)異步操作的復(fù)雜程度較高,程序主要使用回調(diào)方式進(jìn)行處理,與普通人的思維方式有些初入,而且難以調(diào)試。
4、BeginInvoke()和EndInvoke()的使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication
{class Program{static void Main(string[] args){Func<DateTime> func = () =>{Thread.Sleep(1000);return DateTime.Now;};Console.WriteLine($"func.Invoke()={func.Invoke()}");//EndInvoke(r)用來(lái)獲取執(zhí)行后的返回值,BeginInvoke()的第一個(gè)參數(shù)是func執(zhí)行完成后回調(diào)用函數(shù)IAsyncResult asyncResult = func.BeginInvoke(r =>{//Console.WriteLine(func.EndInvoke(r));Console.WriteLine(r.AsyncState);}, "cjavapy");//asyncResult.AsyncWaitHandle.WaitOne();一直等到完成后,才會(huì)執(zhí)行下一行代碼//asyncResult.AsyncWaitHandle.WaitOne(5000);指定等待超時(shí)的時(shí)間為5sConsole.WriteLine(func.EndInvoke(asyncResult));//Thread.Sleep(6000);}}
}
?注意:EndInvoke()
獲取返回值只能調(diào)用一次,不能重復(fù)調(diào)用。