I am implementing an interface that defines an asynchronous method - one that returns a Task<T>
object.
public class ValidationResult
{
// Properties that will hold the results of a validation.
}
public interface IValidator
{
Task<ValidationResult> Validate(object objectToValidate);
}
In most of the classes implementing this interface, there is asynchronous work to do in the Validate
method. Therefore, the async
and await
keywords are leveraged.
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 { /* ... */ };
}
}
However, some of the classes implementing this interface have no asynchronous work to do in the Validate
method.
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 { /* ... */ };
}
}
If the async
keyword is used for the Validate
method in the synchronous scenario above, then I'm getting the CS1998 warning from the compiler.
This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
I understand from one particular question and answer that I can simply implement the method without including the async
keyword and return completed Task
objects.
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 { /* ... */ });
}
}
My question is: What is the best practice for handling Exceptions in this scenario?
If my synchronous code throws an Exception, should I let it fall through to the caller untouched? Or, would it be better to catch it and wrap it in a failed Task
object using Task.FromException<ValidationResult>(ex)
?