【问题标题】:Async JSON deserialisation in ASP.NETASP.NET 中的异步 JSON 反序列化
【发布时间】: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


【解决方案1】:

你的代码是好的。 DeserializeObject 将在线程池线程中运行,因为您使用的是 ConfigureAwait(false)

您的整个方法 (GetDataAsync) 仍将是异步的,因为它将在第一个 await 上返回给调用者。

【讨论】:

  • 旁注:用 ASP.Net 标记的问题在哪里使用 ConfigureAwait(false) 没有任何好处(使用它通常是货物崇拜编程)。如果异步调用之后的代码需要访问请求或当前文化,它也会产生积极的危害(请参阅stackoverflow.com/questions/13489065/… 进行长时间讨论)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-09
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
相关资源
最近更新 更多