2017-02-25 89 views
0

我打电话给这种方法: Windows.Foundation.IAsyncOperation<AppServiceResponse> AppServiceConnection.SendMessageAsync(ValueSet message)我可以写通用扩展方法来运行任务吗?

例如, await connection.SendMessageAsync(initialStatus);

它显示一个错误:“IAsyncOperation”不包含对“GetAwaiter”的定义,并没有扩展方法“GetAwaiter”接受型的第一参数“IAsyncOperation'could中找到(是否缺少using指令关于” ?系统“)

然后我将其更改为:

await Task.Run(() => connection.SendMessageAsync(initialStatus)); 

它得到了编译。

我的第一个问题是为什么我不能等待SendMessageAsync?这意味着什么“GetAwaiter没有定义”?

我的第二个问题是我还需要运行其他方法 Windows.Foundation.IAsyncOperation<AppServiceConnectionStatus> AppServiceConnection.OpenAsync()

我写一个扩展方法:

public static async void AsTask(this IAsyncOperation<AppServiceResponse> operation) 
{ 
    await Task.Run(() => operation); 
} 

所以我可以打电话connection.SendMessageAsync(initialStatus).AsTask();但我可以使扩展方法通用的,所以我也可以拨打像connection.OpenAsync().AsTask();

+1

如果您要使用异步/等待,您_必须返回一个“任务”,“任务”或“无效”。 'IAsyncOperation'不是那些......但是已经有方法可以转换成['WindowsRuntimeSystemExtensions']中的任务(https://msdn.microsoft.com/en-us/library/system.windowsruntimesystemextensions(v = vs .110).aspx)类。 –

+1

请注意,这并不是您想要的。它不在等待异步操作。它产生了一个启动异步操作的新线程。等待的Task的返回值是'IAsyncOperation '。你需要等待。正如Jeff Mercado指出的那样,已经有方法将这些转换为任务。 –

+1

使用Task.Run存在危险的复杂性,您需要非常小心谨慎地操作。请参阅http://blog.stephencleary.com/2013/10/taskrun-etiquette-and-proper-usage.html –

回答

2

My first question is why I cannot apply await to SendMessageAsync? What exactly does it mean "no definition for GetAwaiter"?

这意味着你”重新缺少对System.Runtime.WindowsRuntime.dll的引用。

Then I change it to [use Task.Run ] It got compiled.

是的,但它不会正常工作。正如迈克所评论的那样,Task.Run的返回类型是Task<IAsyncOperation<T>>,当等待时返回(不等待)实际IAsyncOperation<T>。所以你只是开始后台线程上的操作,然后等待那个操作到开始 - 你不等待它到完成

所以,你不应该写一个扩展方法。你不应该在这里使用Task.Run。只需添加缺少的参考,你应该没问题。