Здравствуйте, SergASh, Вы писали:
SAS>Полная реализация метода, которая Task<T> возвращает — длинная простыня в реальном коде. SAS>Чтобы не повторяться, метод, который без возвращаемого значения, вызывает полную версию одним из двух приведенных способов. SAS>Может кто-нибудь объяснить какая разница между этими двумя вариантами?
Первый вариант — засада. Он может даже не начать выполнение таска, который вернет action, не говоря уж о том, что дожидаться выполнения того таска не обязан. В итоге, таск может завершиться уже после освобождения контекста. Ну или попытаться.
Здравствуйте, SergASh, Вы писали:
S>>Первый вариант — засада. Он может даже не начать выполнение таска, который вернет action, не говоря уж о том, что дожидаться выполнения того таска не обязан. В итоге, таск может завершиться уже после освобождения контекста. Ну или попытаться.
SAS>Слона-то я не приметил С делегатом конечно неправильно было. SAS>Тогда остается вопрос про сам метод. Где-то будет разница между такими вариантами?
Здесь мне хотелось бы верить, что разница с точки зрения наблюдаемого поведения не должна быть заметна. А разницу с точки зрения генерации компилятором автомата в случае async/await, не очень хочется обсуждать. Что еще... При отсутствии необходимости обработки исключений, using-ов, перечислителей и прочего, я бы предпочел метод, возвращающий чистый таск, т.е. без async/await.
Полная реализация метода, которая Task<T> возвращает — длинная простыня в реальном коде.
Чтобы не повторяться, метод, который без возвращаемого значения, вызывает полную версию одним из двух приведенных способов.
Может кто-нибудь объяснить какая разница между этими двумя вариантами?
PS Понимаю, что варианта там не два может быть, а четыре, и что асинхронность делегата никак не связана с асинхронностью самого метода.
Не видя полного текста сказать сложно, но пока я вообще не вижу смысла во всех методах.
using (IContext context = BuildContext()) ... в клиентском коде и понеслась.
Если надо гарантированно очистить сontext(), то достаточно
public static async Task<T> ExecuteInContextAsync<T>(Func<IContext, Task<T>> action)
{
using (IContext context = BuildContext())
{
return await action(context);
}
}
public static async Task ExecuteInContextAsync<T>(Func<IContext, Task> action)
{
using (IContext context = BuildContext())
{
await action(context);
}
}
S>Первый вариант — засада. Он может даже не начать выполнение таска, который вернет action, не говоря уж о том, что дожидаться выполнения того таска не обязан. В итоге, таск может завершиться уже после освобождения контекста. Ну или попытаться.
Слона-то я не приметил С делегатом конечно неправильно было.
Тогда остается вопрос про сам метод. Где-то будет разница между такими вариантами?
Здравствуйте, Sinix, Вы писали:
S>Не видя полного текста сказать сложно, но пока я вообще не вижу смысла во всех методах. S>using (IContext context = BuildContext()) ... в клиентском коде и понеслась.
Я упростил конечно основной метод. Там ещё параметры есть, инициализация контекста, логи, обработка ошибок. Всего около 25 строк, которые вовсе не хочется повторять два раза.
К тому же то, как именно строится контекст, клиентскому коду лучше не показывать, а то вдруг кто-то захочет его сохранить куда-нибудь на подольще — и проблемы обеспечены.