Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在我的例子中,将接口方法标记为异步是正确的吗_C#_Asynchronous_Async Await_C# 5.0 - Fatal编程技术网

C# 在我的例子中,将接口方法标记为异步是正确的吗

C# 在我的例子中,将接口方法标记为异步是正确的吗,c#,asynchronous,async-await,c#-5.0,C#,Asynchronous,Async Await,C# 5.0,我正在使用一个自定义框架,该框架在我的公司内使用了很长时间。 我想在代码中使用新的异步特性 为此,我必须将“MyClass”的“ProcessRequestMessage”标记为async。 我无法更改接口“IFramework”和类“FrameworkBase” 框架已经期望“ProcessRequestMessage”异步完成,因此我不必在方法末尾使用“Wait()”。 对“SetResponseCode”的调用向框架发出信号,以最终确定“MyClass”的实例 问题: 我在异步特性的文档中

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

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

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

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

您应该避免
异步void
的主要原因有两个:

public class FrameworkTestBase: FrameworkBase
{
  protected abstract Task ProcessRequestMessageAsync();
  protected override sealed async void ProcessRequestMessage()
  {
    try
    {
      await ProcessRequestMessageAsync();
      SetResponseCode(0);
    }
    catch
    {
      SetResponseCode(-1);
    }
  }
}
  • 调用代码假定方法返回时已完成
  • 它如何处理异常
  • 在您的特定情况下,调用代码不会假定在
    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
      }
    }
    
    或者(使用
    异步void
    ):


    OP提到他们需要
    async
    来支持他们自己的定制框架,我得到的印象是
    Task
    /
    Task
    的概念甚至没有包含在内。
    async
    的自然返回类型是
    Task
    Task
    void
    async
    的非自然返回类型。因此,
    任务
    涉及到了
    异步
    的本质。不过,我同意,鉴于这是一个自定义框架,我认为这有点例外。@StephenCleary我最终使用了您发布的“备选方案”。我知道在这种情况下,特别注意例外情况。所以我想我涵盖了你的两个观点。如果异步特性的语言设计者完全禁止void与async一起使用,可能会更好。这将迫使开发人员编写更多的代码,但至少异常不会如此容易泄漏(在tasks属性中介绍)。无论如何,谢谢。@初学者:当
    async
    /
    wait
    功能最初设计时,它不包括对
    async void
    的支持。后来添加了它(在语言团队的反对意见之上),以启用异步事件处理程序。