2009-11-23 149 views
3

實際上,我很難理解BeginInvoke()和EndInvoke()對。C#異步操作

class AsynchronousDemo 
{ 

    public delegate void DemoDelegate(); 
    static void Main() 
    { 

     DemoDelegate d = PrintA; 

     IAsyncResult AResult = d.BeginInvoke(Callback,null); 
     d.EndInvoke(AResult); 
     Console.ReadKey(true); 
    } 

    static void PrintA() 
    { 
     Console.WriteLine("....Method in Print A Running ...."); 
     Thread.Sleep(4000); 
     Console.WriteLine("....Method in Print A Completed..."); 
    } 


    static void Callback(IAsyncResult ar) 
    { 
     Console.WriteLine("I will be finished after method A 
     completes its execution"); 
    } 
} 

1)我們用 「的EndInvoke()」 來表示的BeginInvoke的結束 「異步操作」()..?

2)這些對的真正用途是什麼?

3)我可以得到一些簡單而好的例子來更好地理解它嗎?

回答

10

想象一下,你有一個長期的任務要做,而且一次只能做一件事。通常情況下,爲了做到這一點,你必須停止做其他事情。

// pseudocode 
Main() { 
    DoLaundry() 
    GoAboutYourDay() 
} 

DoLaundry() { 
    // boring parts here 
} 

現在想象一下,當洗衣服正在製作時,你希望能夠度過你的一天。一種解決辦法是讓別人去做。所以你把它帶到一家清潔商店,告訴他們該做什麼,給他們穿衣服,告訴他們在完成時給你打電話。作爲回報,他們會給你一張票,讓他們在你想要他們時可以再次找到你的衣服。

// pseudocode 
Main() { 
    ticket = DoLaundry.BeginDoing(CallMeWhenDone) 
    GoAboutYourDay() 
    ticket.WaitUntilDone() 
} 

CallMeWhenDone(ticket) { 
    cleanLaundry = DoLaundry.FinishDoing(ticket) 
} 

這就是異步操作的工作原理。

的BeginInvoke你告訴程序,你需要做的工作(委託)是什麼,當它這樣做(回調)叫什麼,做什麼用(州)做到這一點。你得到一個IAsyncResult,它是你需要將它返回以便接收結果的對象。然後你可以做其他的事情,或者使用IAsyncResult中的WaitHandle來阻塞,直到操作完成。

回調:當異步操作完成時,它將調用此方法,爲您提供與以前相同的IAsyncResult。此時,您可以從中檢索您的狀態對象,或將IAsyncResult傳遞給EndInvoke。

EndInvoke:該函數使用IAsyncResult並查找操作的結果。如果它還沒有完成,它會阻塞直到它結束,這就是爲什麼你通常在回調中調用它的原因。

這是一個遍佈整個框架的模式,而不僅僅是函數委託。像數據庫連接,套接字等等,都經常有Begin/End對。

MSDN對這裏的模式文檔:http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.71).aspx

+0

優秀explanation.would是非常有用的像我這樣的初學者。 – user215675 2009-11-23 16:14:39

1

BeginInvoke正在啓動一個異步操作EndInvoke正在等待該函數結束並返回結果。這是在C#中執行線程的另一種方式,其優點是begininvoke從線程池中取出線程,這對於Thread類是不正確的,另一個方法是可以更簡單的方式傳遞參數並將結果傳遞給線程函數。這裏有一個例子http://ondotnet.com/pub/a/dotnet/2003/02/24/asyncdelegates.html

1

我不知道該如何解釋不夠好,但這篇文章應該有所幫助:
Asynchronous Programming Using Delegates MSDN上

摘錄:
........... ..如果BeginInvoke方法被調用,公共語言運行庫(CLR)將請求排隊並立即返回給調用者。目標方法在線程池的線程上異步調用。提交請求的原始線程可以自由地繼續與目標方法並行執行。如果在調用BeginInvoke方法時指定了回調方法,則在目標方法結束時調用回調方法。在回調方法中,EndInvoke方法獲取返回值和任何輸入/輸出或僅輸出參數。如果在調用BeginInvoke的時沒有指定回調方法,EndInvoke會可以從所謂的的BeginInvoke的線程調用.....

1)我們用「的EndInvoke()」來表示結束「異步操作「的BeginInvoke()..?
不,你用它來獲取返回值或...見上

2)什麼是真正使用那些對?
所以,你可以在一個同步的方法等

3)我可以得到一些簡單的和很好的例子更正確地理解它使異步調用?
我敢肯定,谷歌可以做到這一點比我更好:P

1

我用的是調用開始/結束調用構造運行窗口的服務。

例如:

public ServiceName() 
    { 
     //constructor code goes here 
    } 

    protected override void OnStart(string[] args) 
    { 
     ExecuteDelegate ed = new ExecuteDelegate(Execute); 
     AsyncCallback ac = new AsyncCallback(EndExecution); 
     IAsyncResult ar = ed.BeginInvoke(ac, ed); 
     Log.WriteEntry("Service has started."); 
    } 

    protected void EndExecution(IAsyncResult ar) 
    { 
     ExecuteDelegate ed = (ExecuteDelegate)ar.AsyncState; 
     ed.EndInvoke(ar); 
     Stop(); 
     Log.WriteEntry("Service has stopped."); 
    } 

    protected void Execute() 
    { 
     //Code goes here 
     ... 
    } 

    protected override void OnStop() 
    { 
     Log.WriteEntry("Service has stopped."); 
    } 

本質:調用BeginInvoke在一個新的線程啓動的方法執行。當線程結束時,線程加入時調用的方法應該調用EndInvoke。