Replacement for async void

本文关键字:void async for Replacement | 更新日期: 2023-09-27 18:02:57

我正在开发一个用于监控某些任务的应用程序(例如,如果某些服务/网站当前正在启动和运行,数据库中存在某些记录等)。由于大多数任务都是长时间运行的,所以我使用TPLasync/await

我有一个基类用于所有这些任务:

public abstract class LongRunningOperation
{
    // .. some props...
    internal async void Start()
    {
        try
        {
            this.Status = OperationStatus.Started;
            await this.DoStart();
            this.Status = OperationStatus.Finished;
        }
        catch (Exception e)
        {
            this.Status = OperationStatus.Error;
            this.Message = e.ToString();
        }
    }
    protected abstract Task DoStart();
}

启动这些任务的方法如下:

public static LongRunningOperation[] LaunchOperations()
{
    LongRunningOperation[] operations = GetAllLongRunningOperations();
    foreach (var o in operations)
        Task.Factory.StartNew(() => { o.Start(); });
    return operations;
}

该方法返回的数组用于监控所有LongRunningOperation节点并记录状态。目前,我有一个控制台应用程序,它有一个while (true)循环,打印出屏幕上每个操作的状态(名称,状态,当前运行时)(每秒刷新),直到所有操作完成。

困扰我的是async void方法。我读到使用async void方法是不好的做法,但是:

  • 我不知道它们在我的场景中会造成什么伤害
  • 如果我改变Start方法返回Task,它的返回值将永远不会在任何地方使用,我不知道为什么我需要它

如果有人能澄清这些观点,我将不胜感激

Replacement for async void

异步void方法是一种"即发即弃"的操作。您不能等待任何结果,并且不知道操作何时完成以及是否成功。

基本上,当你确定你永远不需要知道操作何时完成以及操作执行是否成功(例如写日志)时,你应该使用void。

使用返回Task的异步方法,调用者能够等待操作完成,并处理在操作执行期间发生的异常。

总之,如果你不需要结果,异步Task稍微好一点,因为你可以等待它,也可以处理异常和处理任务排序。