ASP.NET MVC 5 и WCF асинхронные проблемы - PullRequest
0 голосов
/ 26 ноября 2018

Наше приложение использует WCF в качестве поставщика данных, и на некоторых страницах у нас есть несколько вызовов для различных служб.Хороший кусок для оптимизации, подумал я и начал переписывать его на async.Так что до перезаписи это выглядело как

public ActionResult SomeAction(int id)
{
var r1 = AService.Call1();
var r2 = BService.Call2();
var r3 = CService.Call3();
//another logic
}

и теперь оно перешло на

public async Task<ActionResult> SomeAction(int id)
{
var r1 = await AService.Call1Async();
var r2 = await BService.Call2Async();
var r3 = await CService.Call3Async();
//another logic
}

. При таком подходе я столкнулся с двумя проблемами:

  1. После первого обслуживанияприложение call попадает в бесконечную загрузку и никаких других действий не выполняется.Отладка показывает то же самое - первый звонок и ничего после этого.
  2. Некоторые из наших классов не будут работать с асинхронными методами, например наш статический AuthorizationProvider.

Обновление: @zuckerberg ответ помогает с оптимизацией (ясоздавая задачи и помещая их в ожидаемое Task.WhenAll()), но я все еще получаю зависания на службах WCF - в то время как синхронные вызовы проходят правильно, асинхронные вызовы переводят логику вызовов в спящий режим и никогда не возвращают ее обратно.

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

1. Запуск функций с внутренними асинхронными вызовами из конструктора статического класса - плохая идея, но SomeMethodAsync().Result помогает - конечно, нет никакой выгоды для контроллера, но в этом небольшом случае это приемлемо.

2. Да, я неправильно понял async/await, поэтому я переписал код примерно так:

var get1Task = AService.Call1Async();
var get2Task = BService.Call2Async();
var get3Task = CService.Call3Async();

await Task.WhenAll(get1Task, get2Task, get3Task);
var r1 = get1Task.Result;
var r2 = get2Task.Result;
var r3 = get3Task.Result;
//more logic

Это дало мне хорошее ускорение на страницах с большим количеством вызовов WCF, и я 'Я немного счастлив.

Я благодарю @zuckerberg за указание в правильном направлении.

0 голосов
/ 26 ноября 2018

с async / await они работают асинхронно.Это означает, что они не ждут друг друга или основного потока.Если есть зависимости или вам нужно подождать, пока все 3 не закончат сначала, прежде чем вернуть результат, тогда я предлагаю использовать что-то вроде:

var r1 = await AService.Call1Async();
var r2 = await BService.Call2Async();
var r3 = await CService.Call3Async();

await Task.WhenAll(r1, r2, r3);
//more logic

Надеюсь, это поможет вам подтолкнуть вас в правильном направлении.Однако, не видя больше кода, я не могу сказать, действительно ли при помощи асинхронных / ожидающих вызовов ваши звонки действительно улучшат производительность или нет (это не всегда повышает производительность), и ваши время / усилия могут быть лучше потрачены в другом месте.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...