2015-08-14 77 views
-1

我無法理解asynccallbacks是如何工作的。我有一個方法在一個單獨的類中(稱這個類爲「Foo」),它需要我傳入一個asynccallback方法和一個對象。AsyncCallback的工作原理

該方法應該將一些內容作爲字符串下載。

public void sampleFunction(AsyncCallback callback, object x) 
{ 
    //download some content as a string 
} 

然後,我有我的AsyncCallback方法和從那裏我調用上面的方法我的方法:

public static void test(IAsyncResult result) 
{ 
    Console.WriteLine("Reached"); 

    //Is result the string that should have been downloaded? Confused 
    Console.WriteLine(result); 
} 

public static void sampleFunction2() 
{ 
    Foo z; 
    object t = "hello"; 
    AsyncCallback callback = new AsyncCallback(test); 
    z.sampleFunction(callback, t); 
} 

調用sampleFunction2,沒有打印到控制檯後。我在做什麼/理解錯誤?

+0

'result'的類型是什麼? –

+0

@SKLAK如果你不確定異步如何工作,然後做一個谷歌搜索也閱讀這裏發佈的答案解釋http://stackoverflow.com/questions/24953808/write-your-own-async-method – MethodMan

+0

@MrLister它是一些只包含一個取消異步操作的方法的接口。 – SKLAK

回答

0

我相信幾乎100%你已經完全bastardized使用sampleFunction1sampleFunction2

我相信你的意思的命名約定。

public class Foo 
{ 
    public void BeginSampleFunction(AsyncCallback callback, object x) 
    { 
     //download some content as a string 
    } 

    public string EndSampleFunction(IAsyncResult result) 
    { 
     //download some content as a string 
    } 
} 

測試代碼應該是

public void Test() 
{ 
    AsyncCallback callback = a => 
    { 
     string result = foo.EndSampleFunction(a); 
     Console.WriteLine(result); 
    } 
    object state = null; 
    foo.BeginSampleFunction(callback, state); 
} 

這種模式被稱爲異步編程模型(APM)。它已被完全棄用,不應使用。今天我們使用任務異步編程(TAP)。

在TPL中有一種將方法從APM轉換爲TAP的工廠方法。

public async Task Test() 
{ 
    Task<string> task = Task.Factory.FromAsync(foo.BeginSampleFunction, foo.EndSampleFunction, null); 
    string result = await task; 
    Console.WriteLine(result); 
} 
+0

對不起,這是非常新的。感謝修復 – SKLAK

+0

回調被調用的地方在哪裏?如果你做foo.BeginSampleFunction,你將參數傳遞給一個無所事事的函數。沒有人叫回調。這是行不通的。您需要一個委託並在委託上進行begininvoke。 –

+0

@PhilipStuyck將回調傳遞給'BeginXXX'方法的一點是,當它完成時,它會調用回調函數。沒有委託可以調用'BeginInvoke'。這不是線索。這是異步I/O。 – Aron

1

asynccallback是一個將在異步操作完成時調用的回調函數。它通常作爲參數傳遞給名稱以begin開頭的方法。或者你使用委託,做一個BeginInvoke的

整個過程是由微軟在這裏詳細解釋說:https://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.110).aspx

尋找在我提供的鏈接的最後一個例子。

+0

一旦sampleFunction完成,不會測試被調用嗎? – SKLAK

+0

當然不是,如果你有一個委託給該方法,然後做一個begininvoke然後傳遞迴調,它會被調用。閱讀鏈接中的最後一個例子,我提供了它正是你想要做的。 –

+0

我明白了,那麼應該由sampleFunction下載的字符串會發生什麼變化? – SKLAK

2

我會使用異步等待關鍵字,而不是使用AsyncCallback的較舊(但仍然有效)的方法。

public async Task SampleFunction(object x) 
{ 
    await DownloadAsync(); //Download your string using await 
    //await will block here until "DownloadAsync" returns. It will return control to the calling method and return here when the await finishes (or comes back to finish the method). 
} 

public async static CallerMethod() 
{ 
    await SampleFunction(yourObject); 
    //The code will continue here while the string is downloading and it will pause the execution to finish the callback (after the await) anytime. 
} 

把一個異步方法想象成一個兩部分方法。首先是邏輯和回調(await語句之後的代碼)。

希望這不是太難理解,我可以澄清或重新制定,如果需要。