У меня есть небольшое приложение MVC 5, которое вызывает веб-службу и получает ответ JSON. Я десериализую ответ в свой собственный тип, и он передается в представление, и данные отображаются бритвой.Async JSON deserialisation в ASP.NET
Обработчик контроллер:
public async Task<ActionResult> Search(string q)
{
var vm = new SearchResultViewModel(await _searchService.GetDataAsync(q));
return View(vm);
}
Метод поиска услуг:
public async Task<ISearchResult> GetDataAsync(string q)
{
var fullRequest = new UriBuilder(RequestUri) {Query = "q=" + q};
var result = await _client.GetAsync(fullRequest.ToString()).ConfigureAwait(false);
if (result.IsSuccessStatusCode)
{
var jsonResponse = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
// How should I call this?
return JsonConvert.DeserializeObject<SearchResult>(jsonResponse);
}
return new SearchResult
}
Мой вопрос: Как я должен позвонить JsonConvert.DeserializeObject
? Это операция с привязкой к процессору, так что нормально звонить синхронно (и блокировать поток), так как я не могу вернуться, пока это не будет выполнено? Если есть проблема с десериализацией, токен отмены не может быть использован.
Если я должен позвонить асинхронно, следует ли использовать Task.Factory.StartNew()
, как предложено intellisense, в качестве замены устаревшего JsonConvert.DeserializeObjectAsync()
? This Канал 9 видео предлагает (на 58 минут), что это не такая хорошая идея. Возможно, другой вариант, например Task.Run()
? Возможно, это плохая идея, поскольку это может вызвать проблемы с SyncContext?
Любые указатели с благодарностью получили!
Я не думаю, что существует разница между 'Task.Factory.StartNew()' и 'Task.Run()', за исключением случаев, когда вы не хотите использовать threadpool. Я бы сказал, что ваш код в порядке, как есть (например, десериализовать синхронно), если JSON не будет большим, и в этом случае вы могли бы делать буферизованные данные, считанные из вашего результата result.Content как поток (если возможно) и десериализовать JSON в потоковом режиме, а не сначала выделять всю строку. – jamespconnor
@SimonB: Для справок в будущем не используйте 'Task.Factory.StartNew'; он имеет опасные значения по умолчанию. 'Task.Run' безопаснее. Однако в большинстве случаев ни один из них не должен использоваться на ASP.NET. –
@ StephenCleary Спасибо за головы! Я не уверен, какие варианты использования для ASP.NET, особенно для процессоров, связанных с операциями. Возможно, если у вас есть несколько параллельных задач? Очевидно, что высокий параллелизм имеет свои проблемы в контексте веб-сервера. –