Есть ли способ вызвать асинхронный из синхронного метода, который запускается как задача? - PullRequest
0 голосов
/ 29 ноября 2018

Позвольте мне начать с некоторого кода.У меня есть асинхронный канал данных:

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).

Я ищу решение этой проблемы (включая низкоуровневые / продвинутые хаки), любую помощьоценили!

...