1

我正在使用一个自定义框架,该框架在我的公司内使用了很长时间。我想在我的代码中使用新的异步功能。

为此,我必须将“MyClass”的“ProcessRequestMessage”标记为异步。我无法更改接口“IFramework”和类“FrameworkBase”。

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

问题:我在异步功能的文档中读到,只有 void 事件应该被标记为异步以进入异步工作流(任务不适用于此处)。我的代码要求我将 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);
    }
}
4

1 回答 1

3

您应该避免的主要原因有两个async void

  1. 调用代码假定方法在返回时已完成。
  2. 它如何处理异常。

在您的特定情况下,调用代码在返回时不会假定操作已完成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);
    }
  }
}
于 2013-11-05T13:37:53.317 回答