2012-03-14 134 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! 
} 

我希望帮你