当我运行这段代码一切正常:异步恭候等效
public async void InvokePlugin(MyObject xTask)
{
try
{
var hndlr = new TimeoutHandler(RunTask);
var asyncResult = hndlr.BeginInvoke(xTask, null, new object());
if (!asyncResult.AsyncWaitHandle.WaitOne(xTask.Timeout, false))
{
throw new TimeoutException("Plugin didn't complete processing in a timely manner.");
}
hndlr.EndInvoke(asyncResult);
}
catch (Exception ex)
{
//Handle Exceptions
}
}
private delegate void TimeoutHandler(MyObject xTask);
我想更新该代码使用异步/等待。我试图这样做:
public async void InvokePlugin(MyObject xTask)
{
try
{
var runTask = Task.Run(() => { RunTask(xTask); });
if (await Task.WhenAny(runTask, Task.Delay(xTask.Timeout)) == runTask)
{
// Task completed within timeout.
// Consider that the task may have faulted or been canceled.
// We re-await the task so that any exceptions/cancellation is rethrown.
await runTask;
}
else
{
throw new TimeoutException("Plugin didn't complete processing in a timely manner.");
}
}
catch (Exception ex)
{
//Handle Exceptions
}
}
...但它不工作。很显然,我正在做一些调整。它确实调用了RunTask方法,并执行了前两行罚款,但它只是结束,我似乎无法捕捉TaskRun方法或上面的代码中的异常。我在输出窗口中看到的所有内容都是“程序已退出,代码为0(0x0)”。
如果那里的专家能够指出我做错了什么,或者给我一些关于如何捕捉异常并处理它的建议,我将非常感激。
此外,如果你觉得我错过了任何重要的细节,请问我会更新我的问题。
通常我会说,如果它的工作不解决它,但在这种情况下,我试图重新架构一点,以允许一些增强,所以我在这里。
我注意到的第一件事,避免使用'async void'签名。使用'async Task'来代替主叫方。唯一的例外是WPF和WinForms应用程序中的事件处理程序。 – Igor
'await'与'Wait'不一样。你的原始代码是同步的('WaitOne'),所以它不适合转换为'async/await'。 –
1)将'async void'改为'async Task'。 2)“等待”任务,允许“异步”增长。 3)在你的'Main'方法中,在“顶部”任务中调用'GetAwaiter()。GetResult()'。 –