bmt*_*033 129 c# asynchronous async-await
我正在编写一个将数据传输到USB HID类设备的WinForms应用程序.我的应用程序使用了优秀的Generic HID库v6.0,可以在这里找到.简而言之,当我需要将数据写入设备时,这是被调用的代码:
private async void RequestToSendOutputReport(List<byte[]> byteArrays)
{
foreach (byte[] b in byteArrays)
{
while (condition)
{
// we'll typically execute this code many times until the condition is no longer met
Task t = SendOutputReportViaInterruptTransfer();
await t;
}
// read some data from device; we need to wait for this to return
RequestToGetInputReport();
}
}
Run Code Online (Sandbox Code Playgroud)
当我的代码退出while循环时,我需要从设备中读取一些数据.但是,设备无法立即响应,因此我需要等待此呼叫返回才能继续.因为它目前存在,RequestToGetInputReport()声明如下:
private async void RequestToGetInputReport()
{
// lots of code prior to this
int bytesRead = await GetInputReportViaInterruptTransfer();
}
Run Code Online (Sandbox Code Playgroud)
对于它的价值,GetInputReportViaInterruptTransfer()的声明如下所示:
internal async Task<int> GetInputReportViaInterruptTransfer()
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不熟悉.NET 4.5中新的异步/等待技术的工作原理.我之前对await关键字进行了一些阅读,这让我觉得在RequestToGetInputReport()内部调用GetInputReportViaInterruptTransfer()会等待(也许它会这样做?)但它似乎不是对RequestToGetInputReport()的调用本身正在等待,因为我似乎几乎立即重新进入while循环?
任何人都可以澄清我所看到的行为吗?
Ric*_*ook 209
最重要的是要了解async和await的是,await 不等待相关的调用来完成.如果操作已经完成,则await立即和同步地返回操作的结果是什么,或者如果还没有,则调度继续执行方法的其余部分然后将控制返回给调用者.异步操作完成后,将执行计划的完成.async
问题标题中特定问题的答案是通过调用适当的方法来阻止async方法的返回值(应该是类型Task或Task<T>)Wait:
public static async Task<Foo> GetFooAsync()
{
// Start asynchronous operation(s) and return associated task.
...
}
public static Foo CallGetFooAsyncAndWaitOnResult()
{
var task = GetFooAsync();
task.Wait(); // Blocks current thread until GetFooAsync task completes
// For pedagogical use only: in general, don't do this!
var result = task.Result;
return result;
}
Run Code Online (Sandbox Code Playgroud)
在这段代码片段中,CallGetFooAsyncAndWaitOnResult是异步方法的同步包装器GetFooAsync.但是,大多数情况下应避免使用此模式,因为它将在异步操作期间阻塞整个线程池线程.这是对API公开的各种异步机制的低效使用,它们努力提供它们.
在"等待"的答案并不等待完成调用有几个,更详细的解释这些关键字.
同时,@斯蒂芬克莱里关于async void持有的指导.其他很好的解释可以在http://www.tonicodes.net/blog/why-you-should-almost-never-write-void-asynchronous-methods/和http://www.jaylee.org/找到. post/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void.aspx.
Ste*_*ary 119
避免async void.让你的方法返回Task而不是void.然后你就可以await了.
像这样:
private async Task RequestToSendOutputReport(List<byte[]> byteArrays)
{
foreach (byte[] b in byteArrays)
{
while (condition)
{
// we'll typically execute this code many times until the condition is no longer met
Task t = SendOutputReportViaInterruptTransfer();
await t;
}
// read some data from device; we need to wait for this to return
await RequestToGetInputReport();
}
}
private async Task RequestToGetInputReport()
{
// lots of code prior to this
int bytesRead = await GetInputReportViaInterruptTransfer();
}
Run Code Online (Sandbox Code Playgroud)
Ram*_*ala 59
等待AsynMethod直到完成任务的最佳解决方案
var result = Task.Run(async() => await yourAsyncMethod()).Result;
Run Code Online (Sandbox Code Playgroud)
只需放置 Wait() 等待任务完成
GetInputReportViaInterruptTransfer().Wait();
| 归档时间: |
|
| 查看次数: |
257542 次 |
| 最近记录: |