2012-03-14 209 views
2

我正在使用Windows 8 CP,並發現在我的應用程序中,我無法正確獲取新的異步/等待機制。等待/異步問題

這個方法我顯示你將作爲UnitTest(從單元測試調用)運行,但是當正常運行時,它不工作!

StreamSocket _client; 

private void Start() { 
    SomeMethod(); 
    SomeOtherMethod(); 
} 

private async void SomeMethod(string sample) 
{ 
    var request = new GetSampleRequestObject(sample); 
    byte[] payload = ConvertToByteArray(request, Encoding.UTF8); 

    DataWriter writer = new DataWriter(_client.OutputStream); 
    writer.WriteBytes(payload); 
    await writer.StoreAsync(); // <--- after this executes, it exits the method and continues 
    await writer.FlushAsync(); // <--- breakpoint never reaches here, instead 
    writer.DetachStream(); 
} 

private void SomeOtherMethod() 
{ 
    string hello = "hello"; // <--- it skips everything and reaches here! 
} 

什麼給?

+0

它能做什麼,而不是工作?它的行爲如何? – 2012-03-14 15:30:57

+0

請參閱內嵌註釋顯示執行。 – 2012-03-14 15:32:00

+0

抱歉,我錯過了那些。 – 2012-03-14 15:33:41

回答

5

我認爲你必須把地等待着在開始功能您最初的someMethod電話前:

await SomeMethod();

+0

但是爲什麼它會在單元測試中工作? – 2012-03-14 15:38:24

+0

對不起,我不知道。但是對於await關鍵字,它應該在兩種情況下表現相同。如果你調用一個異步函數/方法,當它到達第一行時,它會返回到調用者,而第一行在開始時也有一個等待(大多數情況下,如果相關操作沒有立即完成)。 – 2012-03-14 15:43:10

+0

也許在你的單元測試中你等待的異步操作會立即返回,所以它們並不是真正異步執行的。在正常運行中,他們確實需要一些時間。 – 2012-03-14 15:46:07

0

因爲它聽起來像你想的someMethod調用SomeOtherMethod之前完成的,你需要把它返回一個任務並等待該任務完成。所有你需要做的就是將聲明中的'async void'改爲'async Task',然後在Start方法中,將調用者改爲SomeMethod()。因爲你不需要等待任務完成,所以一旦方法退出(第一次等待),沒有任何東西可以阻止已完成的任何其他任務。

使用'async void'意味着你不關心它什麼時候完成(或者如果它完成,也可能是)。如果你照顧,你需要使用「異步任務」,然後適當地使用它。

不知道這會幫助解釋,但這裏有一個博客帖子我關於這個問題所做的:

http://blog.sublogic.com/2012/03/06/async-lesson-2-of-n-async-void-probably-isnt-what-you-want/

+1

你不應該在UI線程上調用Wait()。相反,你應該「等待」結果。 – svick 2012-03-15 18:47:59

+0

同意,對不起,我錯過了這是發生在UI線程上 – 2012-03-15 22:24:21

2

我認爲丹尼爾·施洛瑟的答案可能有一些其他的問題。 這裏是我的改進方法:

private async void Start() { 
    await SomeMethod(); 
    SomeOtherMethod(); 
} 

異步函數應以「等待」開頭必定被調用。但是使用異步函數的函數也應該被標記爲「async」。

這就是我的觀點。由於

0

我想你應該編輯:

StreamSocket _client; 

private async Task Start() { 
    await SomeMethod(); 
    SomeOtherMethod(); 
} 

private async Task SomeMethod(string sample) 
{ 
    var request = new GetSampleRequestObject(sample); 
    byte[] payload = ConvertToByteArray(request, Encoding.UTF8); 

    DataWriter writer = new DataWriter(_client.OutputStream); 
    writer.WriteBytes(payload); 
    await writer.StoreAsync(); // <--- after this executes, it exits the method and continues 
    await writer.FlushAsync(); // <--- breakpoint never reaches here, instead 
    writer.DetachStream(); 
} 

private void SomeOtherMethod() 
{ 
    string hello = "hello"; // <--- it skips everything and reaches here! 
} 

我希望幫你