【发布时间】:2019-08-27 18:40:29
【问题描述】:
我正在实现一个定义异步方法的接口 - 返回一个 Task<T> 对象的接口。
public class ValidationResult
{
// Properties that will hold the results of a validation.
}
public interface IValidator
{
Task<ValidationResult> Validate(object objectToValidate);
}
在大多数实现此接口的类中,Validate 方法中都有异步工作要做。因此,async 和 await 关键字被利用。
public class ExampleAsyncValidator : IValidator
{
public override async Task<ValidationResult> Validate(object objectToValidate)
{
// Perform some asynchronous calls here which will use the await keyword.
return new ValidationResult { /* ... */ };
}
}
但是,一些实现此接口的类在Validate 方法中没有异步工作要做。
public class ExampleSyncValidator : IValidator
{
public override async Task<ValidationResult> Validate(object objectToValidate)
{
// Perform only synchronous calls here. No use of the await keyword.
return new ValidationResult { /* ... */ };
}
}
如果async 关键字用于上述同步方案中的Validate 方法,那么我会收到来自编译器的CS1998 警告。
此异步方法缺少“等待”运算符,将同步运行。考虑使用 'await' 运算符来等待非阻塞 API 调用,或使用 'await Task.Run(...)' 在后台线程上执行 CPU 密集型工作。
我从one particular question and answer 了解到,我可以在不包含async 关键字的情况下简单地实现该方法并返回已完成的Task 对象。
public class ExampleSyncValidator : IValidator
{
public override Task<ValidationResult> Validate(object objectToValidate)
{
// Perform only synchronous calls here. No use of the await keyword.
return Task.FromResult(new ValidationResult { /* ... */ });
}
}
我的问题是:在这种情况下处理异常的最佳做法是什么?
如果我的同步代码抛出异常,我应该让它原封不动地传递给调用者吗?或者,将其捕获并使用Task.FromException<ValidationResult>(ex) 将其包装在失败的Task 对象中会更好吗?
【问题讨论】:
-
我让它成为异常气泡,让调用者决定他想做什么。
-
一般来说应该返回一个失败的Task对象。如果一个方法返回一个Task,那么通常期望在尝试观察Task的结果时会在延迟庄园(IE)中抛出异常。这不适用于例如参数检查(null、超出范围等)
标签: c# .net asynchronous async-await task