Replacement for async void
本文关键字:void async for Replacement | 更新日期: 2023-09-27 18:02:57
我正在开发一个用于监控某些任务的应用程序(例如,如果某些服务/网站当前正在启动和运行,数据库中存在某些记录等)。由于大多数任务都是长时间运行的,所以我使用TPL
和async/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
,它的返回值将永远不会在任何地方使用,我不知道为什么我需要它
如果有人能澄清这些观点,我将不胜感激
异步void
方法是一种"即发即弃"的操作。您不能等待任何结果,并且不知道操作何时完成以及是否成功。
基本上,当你确定你永远不需要知道操作何时完成以及操作执行是否成功(例如写日志)时,你应该使用void。
使用返回Task
的异步方法,调用者能够等待操作完成,并处理在操作执行期间发生的异常。
总之,如果你不需要结果,异步Task
稍微好一点,因为你可以等待它,也可以处理异常和处理任务排序。