【发布时间】:2016-03-12 23:24:16
【问题描述】:
我有一个小型 MVC 5 应用程序,它调用 Web 服务并接收 JSON 响应。我将响应反序列化为我自己的类型,然后将其传递给视图,并由 razor 显示数据。
控制器处理程序:
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?这是一个固有的 CPU 绑定操作,所以可以同步调用(并阻塞线程),因为在它完成之前我不能返回?如果反序列化出现问题,则无法使用取消令牌。
如果我应该异步调用,我是否应该按照 intellisense 的建议使用 Task.Factory.StartNew() 来替代已弃用的 JsonConvert.DeserializeObjectAsync()? This 第 9 频道视频建议(在 58 分钟时)这不是一个好主意。也许是另一种选择,例如Task.Run()?可能是个坏主意,因为它可能会导致 SyncContext 问题?
感谢您的指点!
【问题讨论】:
-
我认为
Task.Factory.StartNew()和Task.Run()之间没有任何区别,除非您不想使用线程池。我会说你的代码是好的(例如同步反序列化),除非 JSON 可能很大,在这种情况下你可以从你的result.Content读取缓冲数据作为流(如果可能的话)并反序列化 JSON流方式,而不是先分配整个string。 -
@SimonB:为了以后参考,不要使用
Task.Factory.StartNew;它有危险的默认值。Task.Run更安全。但是,在大多数情况下,两者都不应该在 ASP.NET 上使用。 -
@StephenCleary 感谢您的提醒!我不确定 ASP.NET 的用例是什么,尤其是 CPU 密集型操作。也许如果您有一些并行任务要运行?显然,高并行性在 Web 服务器上下文中存在其自身的问题。
-
@SimonB:CPU 绑定代码应该直接在 ASP.NET 上运行。我不建议在 Web 应用程序中使用任何并行性。
标签: c# asp.net async-await json-deserialization