让我从一些代码开始。我有一个异步数据通道:
interface IChannel
{
Task<byte[]> SendRecv(string command, byte[] request);
}
和同步接口,描述可以在远程服务器上执行的操作:
interface IRemoteServer
{
int DoLongTask(int param);
}
及其使用异步数据通道的实现:
class RemoteServer : IRemoteServer
{
private IChannel _channel;
public int DoLongTask(int param)
{
var request = BitConverter.GetBytes(param);
var response = _channel.SendRecv(nameof(DoLongTask), request).Result;
return BitConverter.ToInt32(response, 0);
}
}
最后是异步编写并使用远程服务器抽象的应用程序:
class Application
{
private IRemoteServer _server;
async Task<int> SomeMethod(int param)
{
return await Task.Run(() => _server.DoLongTask(param));
}
}
以上代码的问题是,尽管通道和应用程序都是异步编写的,但是在远程服务器实现中访问Result
时,它会阻塞线程池线程。假设IRemoteServer
是不可变的,因为它在其他地方使用过,我无法直接控制它的外观。现在,在实现接口(类RemoteServer
)时,我不能使用async
一词,因为C#假定它是普通的同步方法-另一方面,我知道执行该方法时,我已经在任务,因此从理论上讲,我可以在运行时使用async
来同时加入两个任务(Application.SomeMethod
和IChannel.SendRecv
)。
我正在寻找解决该问题的方法(包括低级/高级黑客),感谢您的帮助!