首页 > 解决方案 > HttpClient.SendAsync().ContinueWith() 任务在完成前死亡

问题描述

我正在编写一个 ASP.NET MVC 应用程序并有一个调用 Web 服务的方法。

protected Task ExecuteRequest(HttpClient client, HttpRequestMessage restRequest)
{
    SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
    scheduler = TaskScheduler.FromCurrentSynchronizationContext();

    Task requestTask = client.SendAsync(restRequest).ContinueWith(antecendent =>
            {
                # Process response. Break point here. Doesn't seem to be running unless I spend time stepping through code in debug mode.
            }, scheduler);
    return requestTask;
}


/* ======================================================================
 * This stuff probably doesn't matter but just in case, I'm including it.
 * ====================================================================== */
protected HttpClient GetClient() {
    var clientHandler = new HttpClientHandler();
    if (clientHandler.SupportsAutomaticDecompression)
    {
        clientHandler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    }
    HttpClient client = new HttpClient(clientHandler);
    return client;
}

然后当我调用 ExecuteRequest:Task request = ExecuteRequest(GetClient(), myRequestMessage);ContinueWith 中的断点不会触发。相反,触发此调用的 MVC 请求完成并且页面完成加载,并且在 ContinueWith 前件中没有调用任何代码。我已经放了日志来查看代码是否被命中,但我放在那里的任何东西似乎都没有运行,因为没有任何日志写入他们的文件,而且该代码中的逻辑结果似乎都没有发生。

我的假设是,当 MVC 响应完成时,由 MVC 请求调用的任务与主线程一起终止。如果我在任务启动后在调试模式下单步执行代码,有时代码会运行并且会遇到断点,所以这看起来像是一个竞争条件。

我看过这篇文章,但他们的解决方案是等待任务完成。在将响应返回给用户之前,我不想等待服务调用完成。如果任务尚未完成,我将让用户稍后刷新以查看结果,这些结果仍应在单独的线程上在后台运行……但问题是结果永远不会发生。

为什么看起来“# Process response”位没有运行?

标签: c#asynchronoustaskrace-condition

解决方案


推荐阅读