В приложении ASP.NET 4.5, какой из них лучше для вызова метода async из метода синхронизации?Task.Run vs null SynchronizationContext
var result = Task.Run(() => SomethingAsync()).GetAwaiter().GetResult();
// or
var temp = SynchronizationContext.Current;
try
{
SynchronizationContext.SetSynchronizationContext(null);
return SomethingAsync().GetAwaiter().GetResult();
}
finally
{
SynchronizationContext.SetSynchronizationContext(temp);
}
Примечание: Да, я знаю, что я должен использовать async/await
весь путь вниз, но я спрашиваю о том самом дне, так и вне ASP.NET Ядра фильтров и виды бритвенные не ASync , поэтому, если я хочу вызвать метод async из фильтра или вида бритвы, мне нужно каким-то образом синхронизировать его. Просто используя SomethingAsync().GetAwaiter().GetResult()
приводит к тупику, из-за SynchronizationContext
, поэтому мне нужен способ запускать этот код без SynchronizationContext
.
EDIT Вот простой вспомогательный класс, который оборачивает это до чисто:
public static class Async
{
public static T Run<T>(Func<Task<T>> func)
{
var context = SynchronizationContext.Current;
if (context == null)
{
return func().GetAwaiter().GetResult();
}
SynchronizationContext.SetSynchronizationContext(null);
try
{
return func().GetAwaiter().GetResult();
}
finally
{
SynchronizationContext.SetSynchronizationContext(context);
}
}
public static void Run(Func<Task> func)
{
var context = SynchronizationContext.Current;
if (context == null)
{
func().GetAwaiter().GetResult();
return;
}
SynchronizationContext.SetSynchronizationContext(null);
try
{
func().GetAwaiter().GetResult();
}
finally
{
SynchronizationContext.SetSynchronizationContext(context);
}
}
}
// Example
var result = Async.Run(() => GetSomethingAsync("blabla"));
Подход 'Task.Run' немного более корректен, а подход' SynchronizationContext.Current' немного более эффективен. Какой из них «лучше» - это просто вопрос мнения. –
Я должен был сказать «лучше». Хорошо, мне кажется, что во втором случае нет ничего плохого, поэтому, если он завернут в хорошую статическую функцию, похоже, что должно быть хорошо использовать – Marius
Вам не нужно проверять 'if'. 'SetSynchronizationContext (null)' действительно. –