c# - HttpClient.SendAsync 不等待/锁定执行

标签 c# async-await dotnet-httpclient

var httpResponseMessage = await httpClient.SendAsync(message).ConfigureAwait(false);
var dataStream = await httpResponseMessage.Content.ReadAsStreamAsync();

按照想法应该等待,但无论它做什么,执行都会存在该方法并返回到 UI。当响应到达时,执行将恢复,但那时 UI 已经更新执行已完成,而实际上尚未完成。 等待所有调用方法。

设计时不等待初始方法(Task.Run(() => StartDownload(selectedSchedules));它启动UI方法执行触发httpclient的服务,当调用完成时UI应该更新为进度,但第二个 httpClient.SendAsync 执行完毕,执行返回到 UI

Task.Run(() => StartDownload(selectedSchedules)); //First call, initiated by a button

public async Task StartDownload(SchedulesList list)
{
    //var t = new Task(() => _scheduleServices.Download(list));
    //t.Start();
    //await t;
    await _scheduleServices.DownloadIwcfDb(list, UsbInfoModels);
}

public async Task Download(SchedulesList schedulesList)
{                         
    await DownloadDb(schedulesList);        
}

private async Task DownloadDb(SchedulesList schedulesList)
{
    using (var httpClient = new HttpClient())
    {
        var message = new HttpRequestMessage(new HttpMethod("POST"), ApiCallUrls.GetIwcfSchedules)
        {
            Content = new StringContent(JsonConvert.SerializeObject(schedulesList), Encoding.UTF8, "application/json")
        };

        httpClient.Timeout = TimeSpan.FromMinutes(20);
        var httpResponseMessage= await httpClient.SendAsync(message).ConfigureAwait(false);
        var dataStream = await httpResponseMessage.Content.ReadAsStreamAsync();
        using (Stream contentStream = dataStream, stream = new FileStream(Path.Combine(Directories.SomEDir, Directories.SomeFileName), FileMode.Create, FileAccess.Write, FileShare.None))
        {
            await contentStream.CopyToAsync(stream);
        }
    }
}

添加了调用链,从方法中删除了不相关的代码

最佳答案

您的问题可能出在您的第一次通话中。

在您的代码中:

Task.Run(()=>StartDownload(selectedSchedules)); //First call, initiated by a button
//I assume afterwards you update the ProgressBar or give some other progress feedback

它的作用是:调用StartDownload立即继续执行。所有其他事情(下载等)都在后台发生。请记住,StartDownload 方法不会阻塞;它只是返回一个 Task 对象。如果您不awaitTask对象,代码将继续执行。

我猜你想要的是:调用StartDownload,等待它完成,然后更新进度。

一个快速的解决方案是使用 async 标记按钮的事件处理程序,然后一直使用 async。该方法看起来有点像这样:

private async void HandleEvent()
{
    await StartDownload();
    //update progress
}

我可以向您推荐 Stephen Cleary 的这篇博文,介绍 async-await:https://blog.stephencleary.com/2012/02/async-and-await.html

关于c# - HttpClient.SendAsync 不等待/锁定执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45800334/

相关文章:

当我从 Form1 调用我的方法时,C# 跨线程操作异常

c# - 接口(interface)和继承

c# - 序列化表达式树

javascript - 等待多个异步函数的 promise 链相当于什么?

asp.net-core - 无法使用 Ubuntu 20.04 使 Net5 工作(OpenSSL 连接问题)

c# - 我可以为长继承链中的子类调用最顶层的构造函数吗?

c# - 在 C# 中将 while 循环与 Task.Run() 相结合

node.js - 在 Node 中使用 async wait 对作业进行排队

c# - Web Api 2 Controller 和处理程序之间有五秒的延迟

c# - 同步并发 HttpClient 使用