C# HttpClient PutAsync不发送数据 无需Wait的解决方法
问题根因
PutAsync是异步IO方法,调用后只会返回一个Task对象代表待执行的任务,不会阻塞当前线程等待请求发送完成。
你之前的写法拿到Task之后没有做任何等待操作,代码会立刻继续往下执行,如果当前作用域跑完直接退出(比如控制台Main方法执行到末尾、临时作用域结束触发资源回收),这个还没启动执行的请求任务会直接被终止,自然抓不到任何网络包。
加respone.Wait(100)本质是阻塞当前线程100毫秒,给异步任务留出了执行时间,才能把请求发出去,但这种阻塞写法违背异步编程设计初衷,在UI/ASP.NET这类有同步上下文的场景还很容易引发死锁。
无Wait的正确写法
按照C#异步编程规范使用await等待任务执行即可,注意承载请求逻辑的方法需要标记async,返回值对应改为Task/Task<T>:
// 方法标记async,返回值用Task而非void public async Task SendXmlRequestAsync() { // 注意:HttpClient建议全局单例复用,不要每次请求都new,高并发下会导致端口耗尽 var httpClient = new HttpClient(); string uri = $"http://{IP}:{port}/"; var stringContent = new StringContent(xmlString, Encoding.UTF8, "application/xml"); // await等待请求执行,不会阻塞线程,同时保证请求完整发出 HttpResponseMessage response = await httpClient.PutAsync(uri, stringContent); // 后续如需读取响应可直接用await获取: // string result = await response.Content.ReadAsStringAsync(); }
如果是在旧版非async Main的控制台程序里没法直接用await,也可以用如下兼容写法,推荐优先升级框架版本支持原生async Main:
// 旧版控制台Main方法的兼容写法 static void Main(string[] args) { SendXmlRequestAsync().GetAwaiter().GetResult(); }
注意:不要用
.Result或者无超时的.Wait()在有同步上下文的场景(比如WinForm/WPF/旧版ASP.NET)等待异步任务,极高概率触发死锁。
内容的提问来源于stack exchange,提问作者Groot
相关产品推荐
相关产品推荐

