2009-06-26 16 views

回答

128

async方法完成處理時,自動調用AsyncCallback方法,其中後處理語句可以執行。利用這種技術,不需要輪詢或等待線程完成。

這裏有Async回調使用的一些更多的解釋:

回調模型:回調模式要求我們指定一個方法回調幷包括我們需要在回調方法來完成呼叫的任何狀態。回調模型可以看出,在下面的例子:

static byte[] buffer = new byte[100]; 

static void TestCallbackAPM() 
{ 
    string filename = System.IO.Path.Combine (System.Environment.CurrentDirectory, "mfc71.pdb"); 

    FileStream strm = new FileStream(filename, 
     FileMode.Open, FileAccess.Read, FileShare.Read, 1024, 
     FileOptions.Asynchronous); 

    // Make the asynchronous call 
    IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length, 
     new AsyncCallback(CompleteRead), strm); 
} 

在這個模型中,我們正在創造一個新的AsyncCallback委託,指定一個方法調用(在另一個線程),當操作完成。另外,我們正在指定一些我們可能需要的對象作爲調用狀態。對於這個例子,我們正在發送流對象,因爲我們需要調用EndRead並關閉流。

我們創造在通話結束時被稱爲會看起來像這樣的方法:

static void CompleteRead(IAsyncResult result) 
{ 
    Console.WriteLine("Read Completed"); 

    FileStream strm = (FileStream) result.AsyncState; 

    // Finished, so we can call EndRead and it will return without blocking 
    int numBytes = strm.EndRead(result); 

    // Don't forget to close the stream 
    strm.Close(); 

    Console.WriteLine("Read {0} Bytes", numBytes); 
    Console.WriteLine(BitConverter.ToString(buffer)); 
} 

其它技術等待,直至全熟輪詢

等待完成模型等待完成模型允許您啓動異步調用並執行其他工作。一旦其他工作完成,您可以嘗試結束該呼叫,並且它將阻止,直到異步呼叫完成。

// Make the asynchronous call 
strm.Read(buffer, 0, buffer.Length); 
IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length, null, null); 

// Do some work here while you wait 

// Calling EndRead will block until the Async work is complete 
int numBytes = strm.EndRead(result); 

或者您可以使用等待手柄。

result.AsyncWaitHandle.WaitOne(); 

輪詢模式輪詢方法類似,不同之處在於該代碼將輪詢IAsyncResult,看看它是否已完成。

// Make the asynchronous call 
IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length, null, null); 

// Poll testing to see if complete 
while (!result.IsCompleted) 
{ 
    // Do more work here if the call isn't complete 
    Thread.Sleep(100); 
} 
+3

`System.IO.Path.Combine`是組合路徑的更好方法。 – 2009-07-09 08:02:00

+1

謝謝。我不知道Path.Combine。根據您的建議改變了答案。 – 2009-07-09 08:35:12

27

認爲它這樣。你有一些你想要並行執行的操作。你可以通過使用異步執行的線程來啓用它。這是一種失火和遺忘機制。

但是,有些情況下需要一種機制,您可以在該操作完成時觸發並忘記,但需要通知。爲此,您可以使用異步回調。

該操作是異步的,但在操作完成時會回撥。這樣做的好處是,您不必等待操作直到完成。您可以自由執行其他操作,因此您的線程不會被阻止。

一個這樣的例子將是一個大文件的後臺傳輸。在傳輸過程中,您並不想阻止用戶執行其他操作。一旦傳輸完成,該過程會以異步方式回覆您,您可能會彈出一個消息框,其中顯示'傳輸完成'