Как конвертировать метод void в Task?

Подскажите, как можно конвертировать void в Task.

Task асинхронная отправка, и в отправке файле, как например в данном примере, неплохо было бы иметь именно Task, а не void.

Помогите понять какой возврат дать методу и как правильно изменить, чтобы ниже приведенный void преобразовать в Task.

public void UploadFile(string localFilePath, string remoteFilePath)
{
    // Добавляем ключи.
    var keyFiles = new[]
    {
        new PrivateKeyFile(config.PrivateKeyFilePath, config.PrivateKeyFilePassphrase)
    };

    var methods = new List<AuthenticationMethod>();
    methods.Add(new PrivateKeyAuthenticationMethod(config.UserLogin, keyFiles));

    // Создаем клиента.
    var connexionWithRSA = new ConnectionInfo(config.Host, config.Port, config.UserLogin, methods.ToArray());
    using var client = new SftpClient(connexionWithRSA);

    try
    {
        client.Connect();

        try
        {
            // Отправляем файл.
            using var stream = File.OpenRead(localFilePath);
            client.UploadFile(stream, remoteFilePath, true); // true для readOnly
        }
        catch (Exception exception)
        {
            logger.LogInformation(exception, $"Failed in uploading file [{localFilePath}] to [{remoteFilePath}]");
        }
        finally
        {
            client.Disconnect();
        }
    }
    catch (System.Net.Sockets.SocketException)
    {
        logger.LogInformation($"Invalid {config.Host} or {config.UserLogin}");
    }
    catch (Renci.SshNet.Common.SshAuthenticationException exception)
    {
        logger.LogInformation(exception.Message);
    }

    finally
    {
        client.Disconnect();
    }
}

public Task UploadFileAsync(string localFilePath, string remoteFilePath)
{
   ... 
}

Ответы (1 шт):

Автор решения: aepot

Как уже упомянуто в комментариях, способ сделать метод асинхронным есть.

Вот ваш асинхронный метод

public async Task UploadFile(string localFilePath, string remoteFilePath)
{
    // Добавляем ключи.
    var keyFiles = new[]
    {
        new PrivateKeyFile(config.PrivateKeyFilePath, config.PrivateKeyFilePassphrase)
    };

    var methods = new List<AuthenticationMethod>();
    methods.Add(new PrivateKeyAuthenticationMethod(config.UserLogin, keyFiles));

    // Создаем клиента.
    var connexionWithRSA = new ConnectionInfo(config.Host, config.Port, config.UserLogin, methods.ToArray());
    using var client = new SftpClient(connexionWithRSA);

    try
    {
        await Task.Run(() => client.Connect());

        try
        {
            // Отправляем файл.
            using var stream = File.OpenRead(localFilePath);
            await Task.Run(() => client.UploadFile(stream, remoteFilePath, true)); // true для readOnly
        }
        catch (Exception exception)
        {
            logger.LogInformation(exception, $"Failed in uploading file [{localFilePath}] to [{remoteFilePath}]");
        }
    }
    catch (System.Net.Sockets.SocketException)
    {
        logger.LogInformation($"Invalid {config.Host} or {config.UserLogin}");
    }
    catch (Renci.SshNet.Common.SshAuthenticationException exception)
    {
        logger.LogInformation(exception.Message);
    }
    finally
    {
        client.Disconnect();
    }
}

Еще убрал лишний Disconnect()

Я привел самый простой пример с инкапсуляцией синхронных методов в Task, но по-хорошему, здесь нужно реализовать правильную обертку для асинхронных EAP методов SftpClient (например BeginUploadFile и EndUploadFile) в формат TAP. Это было бы идеальным решением в данном контексте.

Вот, на мой взляд, хороший пример EAP -> TAP преобразования. Еще документация.

→ Ссылка