C# 在我的例子中,将接口方法标记为异步是正确的吗
我正在使用一个自定义框架,该框架在我的公司内使用了很长时间。 我想在代码中使用新的异步特性 为此,我必须将“MyClass”的“ProcessRequestMessage”标记为async。 我无法更改接口“IFramework”和类“FrameworkBase” 框架已经期望“ProcessRequestMessage”异步完成,因此我不必在方法末尾使用“Wait()”。 对“SetResponseCode”的调用向框架发出信号,以最终确定“MyClass”的实例 问题: 我在异步特性的文档中读到,只有无效事件才应标记为异步,才能进入异步工作流(此处不适用任务)。我的代码要求我将void接口方法的实现标记为入口点 那么,我可以这样做:C# 在我的例子中,将接口方法标记为异步是正确的吗,c#,asynchronous,async-await,c#-5.0,C#,Asynchronous,Async Await,C# 5.0,我正在使用一个自定义框架,该框架在我的公司内使用了很长时间。 我想在代码中使用新的异步特性 为此,我必须将“MyClass”的“ProcessRequestMessage”标记为async。 我无法更改接口“IFramework”和类“FrameworkBase” 框架已经期望“ProcessRequestMessage”异步完成,因此我不必在方法末尾使用“Wait()”。 对“SetResponseCode”的调用向框架发出信号,以最终确定“MyClass”的实例 问题: 我在异步特性的文档中
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
的支持。后来添加了它(在语言团队的反对意见之上),以启用异步事件处理程序。