替换为异步void

时间:2016-08-17 11:51:09

标签: c# .net async-await task-parallel-library

我正在开发一个监控某些任务的应用程序(例如,如果某些服务/网站当前正在运行,数据库中存在某些记录,等等)。由于大多数这些任务都是长期运行,因此我将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,则其返回值将永远不会在任何地方使用,我无法理解为什么需要它

如果有人能澄清这些要点,我会很感激

1 个答案:

答案 0 :(得分:5)

异步void方法是"火灾和遗忘"操作。您不能等待任何结果,也不会知道操作何时完成以及是否成功。

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

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

总而言之,如果您不需要结果,则异步Task稍微好一些,因为您可以等待它以及处理异常并处理任务排序。

相关问题