我正在使用我公司长期使用的自定义框架。 我想在我的代码中使用新的异步功能。
为了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);
}
}
答案 0 :(得分:3)
有两个主要原因可以避免async void
:
在您的特定情况下,调用代码不假设在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);
}
}
}