Asyn c версия метода-оболочки - PullRequest
0 голосов
/ 27 января 2020

У меня есть пара методов, предоставляемых мне API. Я sh хочу написать удобный помощник для регистрации времени выполнения указанных методов и любого куска кода в целом.

Методы сценария использования обычно выглядят так:

object       GetData(string statementKey, string parametersJson, out string errorMessage);
Task<object> GetDataAsync(string statementKey, string parametersJson, CancellationToken cancellationToken = default(CancellationToken));

Я написал обертку для метода syn c:

public static T With<T>(string message, Func<T> func)
{
    var watch = new Stopwatch();

    T returned;

    watch.Start();
    try
    {
        returned = func.Invoke();
    }
    catch (Exception exception)
    {
        Log.Logger.Error(exception, $"Error in {message}");
        throw;
    }
    finally
    {
        watch.Stop();
    }

    // Logging logic here

    return returned;
}

(я знаю, что это не работает с пустыми методами, но перегрузка Action тривиальна, если action syn c) .

Теперь, если передан метод Asyn c, я бы измерил неточное время выполнения. Я немного озадачен тем, как мне нужно изменить описанный выше метод для работы с асинхронными c методами.

Я пробовал эту реализацию, но она кажется неправильной.

public static async Task<T> AsyncWith<T>(string message, Func<Task<T>> func)
{
    T returned;


    try
    {
        var watch = new Stopwatch();
        watch.Start();
        returned = await func.Invoke().ConfigureAwait(false);
        watch.Stop();
        // Logging logic here
    }
    catch (Exception exception)
    {
        Log.Logger.Error(exception, $"Error in {message}");
        throw;
    }

    return returned;
}

Shouldn ' я действительно начинаю задание? Я не понимаю, почему он компилируется с T returned вместо Task<T> returned

1 Ответ

1 голос
/ 27 января 2020

Я пробовал эту реализацию, но она кажется неправильной.

Ваша реализация верна.

Разве я не должен начинать задание на самом деле?

Методы возвращают свои задачи «горячим» - т.е. работающим. Поэтому для запуска задачи достаточно вызова func.Invoke().

Я не понимаю, почему он компилируется с возвращенным T, а не с возвращенной задачей

Поскольку async ключевое слово обрабатывает создание оболочки Task<T> для вас и преобразует return операторов (или исключений) в logi c, который завершает Task<T>.

...