.net的異步調用
最近幾天因為要用到.net的異步,就上網找了找相關的資料。
結果發現網上相關的資料好少,而且基本是以MSDN的這份文檔進行了實作:
下面我也講講這幾天對.Net異步調用的心得:
一:異步調用:在.net裏進行異步調用的方法有
使用線程(Thread) 和 定義與調用方法具用相同簽名的委託進行調用(此時該委託會自動產生BeginInvoke()).
因我只研究了後者,故下面的描述都是指以後者起始的異步調用。
二:異步調用與被調用的方法無關,它不需要因為被異步調用而做任何特殊處理。它的決定權在於調用方。
三:異步的執行與返回:異步調用使用BeginInvoke起始調用和以EndInvoke結束調用並取得返回值,其具體方法有4種:
1,直接在同步的某點調用異步的EndInvoke()阻塞方法
2,使用WaitHandle等待異步調用完成
3,使用輪詢異步調用完成
4,異步完成時執行回調方法通知完成
四:經過這兩天的調試後,我產生了一些疑惑:
1,我在MSDN裏看到這樣的段話:警告 始終在非同步調用完成後調用 EndInvoke。
此方法在MSDN上的描述是:检索由传递的 IAsyncResult 对象表示的异步操作的返回值。
可是如果我不需要在異步方法裏返回值時,應該就可以不需要吧?否則它就會造成“如果尚未完成异步操作,此函数将阻塞,直至结果可用。”
2,針對使用WaitHandle等待方法,我很疑惑下面這一段代碼中紅色標識的這句有什麼意義?
既然EndInvoke就會執行等待阻塞的動作,為什麼還要畫蛇添足,加上一個ar.AsyncWaitHandle.WaitOne()?
3,有關回調,我在回調方法裏加了EndInvoke的方法,可是在執行時及偵錯時卻發現並未執行到這句代碼。如下程式,它在執行到藍色底色那句代碼後便結束了。除非我在藍色底色代碼處等待足夠異步方法運行完的時間,它才會進入到我的回調方法裏。這裏是否正常?
結果發現網上相關的資料好少,而且基本是以MSDN的這份文檔進行了實作:
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cpguide/html/cpconasynchronousprogrammingdesignpattern2.asp
這本正常,然而我對其進行實作後,欲進一步了解異步調用時,卻發現無法再找到進一步的資訊。下面我也講講這幾天對.Net異步調用的心得:
一:異步調用:在.net裏進行異步調用的方法有
使用線程(Thread) 和 定義與調用方法具用相同簽名的委託進行調用(此時該委託會自動產生BeginInvoke()).
因我只研究了後者,故下面的描述都是指以後者起始的異步調用。
二:異步調用與被調用的方法無關,它不需要因為被異步調用而做任何特殊處理。它的決定權在於調用方。
三:異步的執行與返回:異步調用使用BeginInvoke起始調用和以EndInvoke結束調用並取得返回值,其具體方法有4種:
1,直接在同步的某點調用異步的EndInvoke()阻塞方法
2,使用WaitHandle等待異步調用完成
3,使用輪詢異步調用完成
4,異步完成時執行回調方法通知完成
四:經過這兩天的調試後,我產生了一些疑惑:
1,我在MSDN裏看到這樣的段話:警告 始終在非同步調用完成後調用 EndInvoke。
此方法在MSDN上的描述是:检索由传递的 IAsyncResult 对象表示的异步操作的返回值。
可是如果我不需要在異步方法裏返回值時,應該就可以不需要吧?否則它就會造成“如果尚未完成异步操作,此函数将阻塞,直至结果可用。”
2,針對使用WaitHandle等待方法,我很疑惑下面這一段代碼中紅色標識的這句有什麼意義?
既然EndInvoke就會執行等待阻塞的動作,為什麼還要畫蛇添足,加上一個ar.AsyncWaitHandle.WaitOne()?
public class AsyncMain {
static void Main(string[] args) {
int threadId;
AsyncDemo ad = new AsyncDemo();
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
IAsyncResult ar = dlgt.BeginInvoke(3000, out threadId, null, null);
Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",
AppDomain.GetCurrentThreadId());
ar.AsyncWaitHandle.WaitOne();
string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
}
}
static void Main(string[] args) {
int threadId;
AsyncDemo ad = new AsyncDemo();
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
IAsyncResult ar = dlgt.BeginInvoke(3000, out threadId, null, null);
Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",
AppDomain.GetCurrentThreadId());
ar.AsyncWaitHandle.WaitOne();
string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
}
}
3,有關回調,我在回調方法裏加了EndInvoke的方法,可是在執行時及偵錯時卻發現並未執行到這句代碼。如下程式,它在執行到藍色底色那句代碼後便結束了。除非我在藍色底色代碼處等待足夠異步方法運行完的時間,它才會進入到我的回調方法裏。這裏是否正常?
public void AsyncHandle(IAsyncResult iar)
{
if(iar.IsCompleted)
{
Console.WriteLine("Async Handle found the Async is end!");
AsynCall ac=(AsynCall)iar.AsyncState;
ac.EndInvoke(iar);
}
}
[STAThread]
public static void Main()
{
Async2 x=new Async2();
Console.WriteLine("Now is:"+System.DateTime.Now);
AsynCall ac=new AsynCall(x.MyAsync);
AsyncCallback acb=new AsyncCallback(x.AsyncHandle);//定義Handle
IAsyncResult iar=ac.BeginInvoke( 6000,acb,ac);//開始執行異步,並轉交Handle.
x.MyMethod1(2000);
Console.WriteLine("--The Main Method was ended at:"+System.DateTime.Now);
}
{
if(iar.IsCompleted)
{
Console.WriteLine("Async Handle found the Async is end!");
AsynCall ac=(AsynCall)iar.AsyncState;
ac.EndInvoke(iar);
}
}
[STAThread]
public static void Main()
{
Async2 x=new Async2();
Console.WriteLine("Now is:"+System.DateTime.Now);
AsynCall ac=new AsynCall(x.MyAsync);
AsyncCallback acb=new AsyncCallback(x.AsyncHandle);//定義Handle
IAsyncResult iar=ac.BeginInvoke( 6000,acb,ac);//開始執行異步,並轉交Handle.
x.MyMethod1(2000);
Console.WriteLine("--The Main Method was ended at:"+System.DateTime.Now);
}
以上看法或問題,歡迎大家進行討論。
因學習時間尚短,且身邊資料不足,文中不對的地方,請大家多多PP!