我想触发一些操作,运行任务返回函数,然后运行一些其他异步函数,最后等待第一个任务并处理异常(如果有)。
因为我无法确定我的函数是异步的(抛出异常将被推迟,直到我调用
await
)还是非异步的(任何异常都会立即抛出),所以我提出了这个解决方案。但也许我正在重新发明轮子或做一些完全奇怪的事情:
async Task RunMethod() => await instanceObject.Method();
Task task = RunMethod();
...
try
{
await task;
}
catch(Exception e)
{
// handle here
}
你所做的事情是正确的。使用 async/await 是包装异常以便异步抛出异常的最简单方法。
您可以拥有一个单独的异步方法并在任何地方使用它,而不是使用单独的 async/await 辅助方法来包装每个主要异步方法:
public static async Task Run(Func<Task> action) => await action();
使用示例:
Task task = Run(() => instanceObject.DoSomethingAsync());
由
DoSomethingAsync
同步抛出的任何异常都将在结果 task
中被捕获。
如果您想知道如何在不使用 async/await 的情况下实现相同的功能,有很多方法,其中之一是使用
Task
构造函数,以及方法 RunSynchronously
和 Unwrap
:
public static Task Run(Func<Task> action)
{
Task<Task> taskTask = new(action, TaskCreationOptions.DenyChildAttach);
taskTask.RunSynchronously(TaskScheduler.Default);
return taskTask.Unwrap();
}
在所有三种情况下(成功执行、失败、取消),此
Run
与前一个单行 Run
具有完全相同的行为。生成 action
的 Task
在当前线程上同步调用。