Justin

--见天地,见众生,见自己

导航

.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()?
public class AsyncMain {
    
static void Main(string[] args) {
        
int threadId;
        AsyncDemo ad 
= new AsyncDemo();
        AsyncDelegate dlgt 
= new AsyncDelegate(ad.TestMethod);
        IAsyncResult ar 
= dlgt.BeginInvoke(3000out threadId, nullnull);
        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);
        }

以上看法或問題,歡迎大家進行討論。
因學習時間尚短,且身邊資料不足,文中不對的地方,請大家多多PP!

posted on 2005-09-01 15:57  HappyMan  阅读(1592)  评论(4编辑  收藏  举报