首页 > 解决方案 > 有没有办法从作为任务运行的同步方法调用异步?

问题描述

让我从一些代码开始。我有一个异步数据通道:

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.SomeMethodIChannel.SendRecv)。

我正在寻找这个问题的解决方案(包括低级/高级黑客),任何帮助表示赞赏!

标签: c#asynchronousasync-await

解决方案


推荐阅读