Дано:Почему эта оболочка для синхронизации по асинхронному методу работает?
- Наследство не Асинхр метод API на веб-службы ASP.NET/WCF
- Новая асинхронная внутренняя библиотека
- Новый контроллер асинхронной Web API, который должен использоваться в будущем
- Объект «поставщик хранилища», который имеет только асинхронный интерфейс. Его тесты проходят при запуске асинхронно и при синхронном запуске вне контекста запроса.
Опция «go async all the way» не находится на столе, так как она нарушила бы обратную совместимость.
public class Impl {
// This works fine when used asynchronously
public Task<Guid> SaveThingAsync(Thing thingToSave) {
return await _storageProvider.saveAsync(thingToSave);
}
public Guid SaveThing(Thing thingToSave) {
// "Obviously", this code creates a deadlock when called
// from within the request context
// return SaveThingAsync(thingToSave).Result
// Not so obviously, this also creates a deadlock
// return SaveThingAsync(thingToSave)
// .ConfigureAwait(false)
// .GetAwaiter()
// .GetResult()
// This was deadlocking, but magically stopped
// return Task.Run(
// async() => await SaveThingAsync(thingToSave)
// .ConfigureAwait(false)
// ).Result;
// This one works
var saveTask = Task.Run(async() =>
await SaveThingAsync(thingToSave)));
var result = saveTask.ConfigureAwait(false).GetAwaiter().GetResult();
return result;
}
Почему?
Ну, это раздражает. Вчера я получал исключение TaskCancelled при запуске первого примера «Task.Run». Поскольку наши клиенты не просто используют ссылку на прямую службу, но вместо этого клиентскую библиотеку, созданную на наших интерфейсах, изменение интерфейса SOAP приведет к сломанию всего. – Eris
@ Эрис клиент не может сказать, как сказал Стивен. Это не проблема совместимости. Это объясняется здесь: http://stackoverflow.com/a/22591516/122718 – usr
@Eris: Первый (прокомментированный) пример 'Task.Run' действительно, * действительно * странный. Он изгибает мой мозг, пытаясь понять, что он будет делать. Прохождение структур 'ConfiguredTaskAwaitable' не является идиоматическим. Вы должны иметь возможность использовать свой собственный (асинхронный) интерфейс на сервере вместо синхронного интерфейса, потребляемого клиентами - к сожалению, это (логически) дублирует описание интерфейса. –