c# - 解决警告 CS1998 : This async method lacks 'await' operators 时如何处理异常

标签 c# .net asynchronous async-await task

我正在实现一个定义异步方法的接口(interface) - 一个返回 Task<T> 的接口(interface)对象。

public class ValidationResult
{
    // Properties that will hold the results of a validation.
}

public interface IValidator
{
    Task<ValidationResult> Validate(object objectToValidate);
}

在大多数实现此接口(interface)的类中,Validate 中有异步工作要做。方法。因此,asyncawait关键字被利用。

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 中,一些实现此接口(interface)的类没有异步工作要做方法。

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 警告。

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.

我从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 中会更好吗?对象使用 Task.FromException<ValidationResult>(ex)

最佳答案

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(ex)?

你应该把它放在返回的Task上;即,使用 Task.FromException

public override Task<ValidationResult> Validate(object objectToValidate)
{
  try
  {
    // Perform only synchronous calls here. No use of the await keyword.
    return Task.FromResult(new ValidationResult { /* ... */ });
  }
  catch (Exception ex)
  {
    return Task.FromException<ValidationResult>(ex);
  }
}

或者,您可以使用不带 awaitasync 并使用 #pragma 抑制警告:

#pragma warning disable 1998
public override async Task<ValidationResult> Validate(object objectToValidate)
#pragma warning restore 1998
{
  // Perform only synchronous calls here. No use of the await keyword.
  return new ValidationResult { /* ... */ };
}

如果您经常这样做,您可以考虑创建一个辅助方法。 This one是 Nito.AsyncEx 的一部分:

public static class TaskHelper
{
#pragma warning disable 1998
  public static async Task ExecuteAsTask(Action func)
#pragma warning restore 1998
  {
    func();
  }

#pragma warning disable 1998
  public static async Task<T> ExecuteAsTask<T>(Func<T> func)
#pragma warning restore 1998
  {
    return func();
  }
}

因此,如果您安装了 Nito.AsyncEx 或在您的项目中包含上面的代码,那么您可以像这样使用 ExecuteAsTask 方法:

using static Nito.AsyncEx.TaskHelper;
...
public override Task<ValidationResult> Validate(object objectToValidate)
{
  return ExecuteAsTask(() => {
    // Perform only synchronous calls here. No use of the await keyword.
    return new ValidationResult { /* ... */ };
  });
}

关于c# - 解决警告 CS1998 : This async method lacks 'await' operators 时如何处理异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55542514/

相关文章:

c# - 如何使用 C# 使 Excel 单元格范围不可编辑

C# 部署我的应用程序 - 仅从 Web clickonce

c# - 如何发送电子邮件和回滚更改?

64 位操作系统上的 .Net WinForm 系统蜂鸣声

ios - XC测试 : Can expectationForPredicate fulfill on async variable change?

javascript - Node.js 套接字解释

android - robospice 如何管理 Activity 生命周期?

c# - 从 C# 应用程序自动收集统计数据

C# 泛型 - 我可以将此类变成泛型吗?

c# - 如何格式化 DateTime 或 TimeZone/TimeZoneInfo 以显示三个字母?