Преобразование синхронных методов с параметрами Action / Fun c в асинхронные - PullRequest
0 голосов
/ 08 января 2020

Я посмотрел вокруг и не могу найти этот вопрос нигде.

Учитывая следующий метод:

public TOut WithThing<TOut>(Func<T, TOut> func)
{
  var thing = CreateThing();
  thing.DoSomething();
  return func(thing);
}

У меня есть эквивалентный void метод, который оборачивается выше когда я не хочу возвращать значение (это действительно вызывает WithThing<bool> и просто отбрасывает результат):

public void WithThing(Action<T> action)
{
  WithThing(x =>
  {
    action(x);
    return false;
  });
}

Я пытаюсь создать асинхронные версии описанных выше методов, потому что "Thing" имеет синхронные и асинхронные методы.

I думаю эквивалент первого метода:

public async Task<TOut> WithThing<TOut>(Func<T, Task<TOut>> func)
{
  var thing = CreateThing();
  await thing.DoSomethingAsync().ConfigureAwait(false);
  return await func(thing).ConfigureAwait(false);
}

Я не думал, что мне понадобится ConfigureAwait Но Visual Studio их предлагает. Это правильно? Зачем мне нужны ConfigureAwait?

Если приведенный выше код верен, то я бы предположил, что подпись для эквивалента, который не возвращает значение, будет public async Task WithThing(Func<T, Task> func). Каким будет тело?

1 Ответ

0 голосов
/ 08 января 2020

Помните, что использование ConfigureAwait(false) является контекстным, и вы должны знать, когда его не использовать. Обратитесь к ConfigureAwait FAQ и Async / Await - Рекомендации по асинхронному программированию - Настройка контекста .

Ваше предположение о типах возврата равно правильно.

Я бы не стал слишком много переносить, так как это добавляет выделения и делегирует вызовы.

Для части syn c я бы сделал что-то вроде этого:

public TOut WithThing<TOut>(Func<T, TOut> func)
{
  Someting();
  return func(thing);
}

public void WithThing(Action<T> action)
{
  Someting();
  action(x);
}

private void Someting()
{
  var thing = CreateThing();
  thing.DoSomething();
}

и для асин c:

public async Task<TOut> WithThing<TOut>(Func<T, Task<TOut>> func)
{
  await SometingAsync();
  return await func(thing).ConfigureAwait(false);
}

public async Task WithThing(Func<Task> action)
{
  await SometingAsync();
  await action(thing).ConfigureAwait(false);
}

private void SometingAsync()
{
  var thing = CreateThing();
  await thing.DoSomethingAsync().ConfigureAwait(false);
}
...