在我的情况下,将接口方法标记为异步是正确的事情

时间:2013-11-05 11:07:00

标签: c# asynchronous async-await c#-5.0

我正在使用我公司长期使用的自定义框架。 我想在我的代码中使用新的异步功能。

为了todo,我必须将“MyClass”的“ProcessRequestMessage”标记为异步。 我无法更改界面“IFramework”和类“FrameworkBase”。

框架期望已经“ProcessRequestMessage”异步完成,因此我不必在方法的结尾使用“Wait()”。 对“SetResponseCode”的调用向框架发出信号,以最终确定“MyClass”的实例

问题: 我在异步功能的文档中读到,只有void Events应该被标记为async以进入异步工作流程(任务不适用于此处)。我的代码要求我将void接口方法的实现标记为入口点。

我可以这样做:

interface IFramework
{
    void ProcessRequestMessage()

    void SetResponseCode(int code)
}

public abstract class FrameworkBase: IFramework
{
    abstract void ProcessRequestMessage()

    public void SetResponseCode(int code)
    {
        //internal implementation
    }
}

public class MyClass: FrameworkBase
{

    protected override async void ProcessRequestMessage()
    {
        //await something

        SetResponseCode(0);
    }
}

1 个答案:

答案 0 :(得分:3)

有两个主要原因可以避免async void

  1. 调用代码假定方法在返回时已完成。
  2. 如何处理异常。
  3. 在您的特定情况下,调用代码假设在ProcessRequestMessage返回时操作已完成,因此您可以使用async void但是你必须非常小心你的例外情况。 (我更喜欢使用任务延续而不是async void)。

    我建议只为此写一个FrameworkTaskBase

    public class FrameworkTestBase: FrameworkBase
    {
      protected abstract Task ProcessRequestMessageAsync();
      protected override sealed void ProcessRequestMessage()
      {
        ProcessRequestMessageAsync().ContinueWith(t =>
        {
          if (t.IsFaulted || t.IsCanceled)
            SetResponseCode(-1);
          else
            SetResponseCode(0);
        });
      }
    }
    
    public class MyClass: FrameworkBase
    {
      protected override async Task ProcessRequestMessageAsync()
      {
        //await something
      }
    }
    

    或者(使用async void):

    public class FrameworkTestBase: FrameworkBase
    {
      protected abstract Task ProcessRequestMessageAsync();
      protected override sealed async void ProcessRequestMessage()
      {
        try
        {
          await ProcessRequestMessageAsync();
          SetResponseCode(0);
        }
        catch
        {
          SetResponseCode(-1);
        }
      }
    }