小编典典

异步/等待 - 何时返回任务与无效?

all

在什么场景下想要使用

public async Task AsyncMethod(int num)

代替

public async void AsyncMethod(int num)

我能想到的唯一情况是您是否需要任务能够跟踪其进度。

另外,在下面的方法中,是否不需要 async 和 await 关键字?

public static async void AsyncMethod2(int num)
{
    await Task.Factory.StartNew(() => Thread.Sleep(num));
}

阅读 135

收藏
2022-03-06

共1个答案

小编典典

  1. 通常,您会想要返回一个Task. 主要的例外应该是当您 需要 返回void类型(用于事件)时。如果没有理由不允许调用者await执行任务,为什么不允许呢?

  2. async返回的方法void在另一个方面是特殊的:它们代表 顶级异步操作 ,并且当您的任务返回异常时有额外的规则发挥作用。最简单的方法是通过一个示例来显示差异:

    static async void f()
    {
    await h();
    }

    static async Task g()
    {
    await h();
    }

    static async Task h()
    {
    throw new NotImplementedException();
    }

    private void button1_Click(object sender, EventArgs e)
    {
    f();
    }

    private void button2_Click(object sender, EventArgs e)
    {
    g();
    }

    private void button3_Click(object sender, EventArgs e)
    {
    GC.Collect();
    }

f的异常总是被“观察到”的。离开顶级异步方法的异常被简单地视为任何其他未处理的异常。g的异常从未被观察到。当垃圾收集器来清理任务时,它看到任务导致异常,并且没有人处理异常。发生这种情况时,TaskScheduler.UnobservedTaskException处理程序运行。你不应该让这种情况发生。要使用您的示例,

public static async void AsyncMethod2(int num)
{
    await Task.Factory.StartNew(() => Thread.Sleep(num));
}

是的,在这里使用asyncawait,它们确保您的方法在抛出异常时仍然可以正常工作。

有关详细信息,请参阅:https ://docs.microsoft.com/en-us/archive/msdn-
magazine/2013/march/async-await-best-practices-in-asynchronous-
programming

2022-03-06