使用Async方法实现Void接口签名



假设我正在开发一个c#库,该库使用具有以下签名的接口,例如:

public interface IMyInterface
{
public void DoWork();
}

我有两个不同的类实现这个接口。

  • 一个只运行同步代码(所以void返回类型将是好的)。
  • 需要等待异步调用的一个(因此,理想情况下,我希望DoWorkasync Task,而不是void)。

非异步类不是问题,因为它真正只需要一个void返回类型:

public class NonAsyncClass : IMyInterface
{
public void DoWork()
{
Console.WriteLine("This is a non-Async method");
}
}

但我正在努力思考实现async类的最佳方法。我在想这样的事情:

public class AsyncClass : IMyInterface
{
public void DoWork()
{
var t = Task.Run(async () => {
await ExternalProcess();
});
t.Wait();
}
}

但是感觉这不是正确的做事方式。

什么是最好的方法对一个接口程序(假设你没有更改任何控制的接口签名)void返回类型的方法需要async吗?反之亦然,当方法没有任何异步代码时,一个程序如何针对asyc Task返回类型?

当方法需要异步时,针对具有void返回类型的接口(假设您无法控制更改任何接口签名)进行编程的最佳方法是什么?

这本质上和问"什么是阻塞异步代码的最好方法"是一样的,答案是一样的:没有最好的方法。正如我在MSDN的一篇文章中所描述的那样,有各种各样的破解方法,但没有一种破解方法适用于所有场景。

block -threadpool-hack (Task.Run(async () => await ExternalProcess()).GetAwaiter().GetResult();)可能在大多数场景中工作;只有当ExternalProcess必须访问与特定上下文相关的东西(例如,UI元素或HttpContext.Current),或者它依赖于由一个线程一次上下文提供的隐式同步时,它才会失败。所以只要你的ExternalProcess不需要一个特定的上下文,如果它是线程安全的,那么阻塞线程池hack应该工作。

反之亦然,当方法没有任何异步代码时,程序如何针对异步任务返回类型?

这个很简单。异步兼容(例如,Task返回)接口方法意味着的实现可以是异步的,而不是它必须是异步的。同步实现可以使用Task.FromResultTask.FromException来创建返回的Task。或者,您可以将方法标记为async并忽略编译器警告,这是我的AsyncEx库采用的方法。

如果ExternalProcess返回void,则不能对void使用await。编译器将告诉您何时尝试编译代码。因为interface.

如果ExternalProcess返回为"Task"数据类型你的代码必须工作良好。

在示例代码中不清楚。要将异步操作转换为同步操作?当用户调用DoWork方法时,程序将被阻塞,直到操作完成并继续执行下一行代码。

相关内容

  • 没有找到相关文章