自从我潜入C#编程以来已经过去了4周。这真的很有趣,然而,我的屁股很痛苦:
当我单独使用HttpClient.PostAsync()
启动任务时,它可以正常工作。但如果我继续其他事情,原始任务将被取消,而不是我。看起来这个任务不乐意继续。
Task<HttpResponseMessage> task0;
Task task1;
using (var client = new HttpClient())
{
HttpContent content = new ByteArrayContent(new byte[]{});
task0 = client.PostAsync("<valid http address>", content);
task1 = task0.ContinueWith((t) =>
{
// Do nothing
});
}
task1.Wait();
// I got task0.IsCanceled == true here
我试过了:
1,在task0.wait()
之后立即添加PostAsync()
将解决问题,但这不是我想要的。因为我需要异步的性能优势并且这样做会使它完全同步。
2,在task0.wait()
之前添加task1.wait()
会导致TaskCanceledExcpetion
。
3,删除task1
并等待task0
即可。
4,调用task0.start()
将得到&#34;启动可能不会在承诺式任务上被调用。&#34;
所以,有人告诉我,我做错了什么?
PS:
在我问这个问题之前,我用Google搜索了好几天。 StackOverflow的一些问题看起来可能相关,但事实证明它们与我的不一样。
Who canceled my Task?她/他在问为什么继续任务没有被执行。
Why does TaskCanceledException occur?她/他搞砸了我从未做过的取消令,并得到了意想不到的结果。
我也读过这个Task Cancellation但仍然没有任何线索。
答案 0 :(得分:7)
您的HttpClient
最有可能在PostAsync
完成之前被处理掉。删除using
语句用于测试目的,一切都将按预期工作。当请求完成时,您应该将您的客户端部署在不同的位置。
此外,如果您的应用程序逻辑允许,许多人会建议尽可能多地重用HttpClient
的单个实例。
答案 1 :(得分:5)
所以,这个代码似乎在你连接延续时就处理HttpClient
,这很可能不是你想要的。
如果要使用using
语句来处置客户端实例,则需要使用async
和await
关键字。以下代码等同于您的示例,编译器会为您提供延续。
public async Task FooAsync()
{
using (var client = new HttpClient())
{
HttpContent content = new ByteArrayContent(new byte[]{});
await client.PostAsync("<valid http address>", content);
// Continue your code here.
}
}
如果你想继续使用在没有编译器帮助的情况下创建的continuation,你可以将处理逻辑放在一个延续中:
Task<HttpResponseMessage> task0;
Task task1;
var client = new HttpClient();
HttpContent content = new ByteArrayContent(new byte[]{});
task0 = client.PostAsync("<valid http address>", content);
task1 = task0.ContinueWith((t) =>
{
client.Dispose();
})
task1.Wait();