异步等效

时间:2017-03-29 19:04:09

标签: c# asynchronous async-await task-parallel-library task

当我运行此代码时,一切正常:

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);

我想更新此代码以使用Async / Await。我尝试这样做:

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方法并执行前2行,但它刚刚结束,我似乎无法在TaskRun方法或上面的代码中捕获异常。我在输出窗口中看到的只是“程序已退出,代码为0(0x0)。”

如果那里的专家可以指出我做错了什么,或者就如何抓住异常并处理它给我建议我会非常感激。

如果您觉得我错过了任何重要的细节,请询问,我会更新我的问题。

通常我会说它是否有效但不修复它但在这种情况下我试图重新构造一点以允许一些增强,所以我在这里。

1 个答案:

答案 0 :(得分:3)

  1. async void更改为async Task。有关详细信息,请参阅我在async best practices上的文章。
  2. 执行此操作后,异步使用它:

    1. await任务,允许async成长。
    2. asyncawait自然会在您的代码库中向上增长,直到它们达到Main,而不是async

      1. Main方法中,在“顶部”任务上调用GetAwaiter().GetResult()
      2. Blocking on asynchronous code is generally not a good idea,但在控制台应用的Main方法中阻止单个任务是该规则的一个例外。