给定代码类似于
Task.Run(() =>
{
using (var client = new HttpClient())
{
var responseTask = client.GetAsync(urlToInvoke);
}
});
在这种情况下,似乎
GetAsync
实际上并没有运行。任务是在完成之前取消还是这里实际发生了什么?现在,如果你稍微改变一下并插入
Task.Run(() =>
{
using (var client = new HttpClient())
{
var responseTask = client.GetAsync(urlToInvoke);
Task.Delay(5000).Wait()
}
});
GetAsync
确实完全执行。这里发生了什么?是 Task.Delay
将自身关联到 responseTask
中的同一个任务最终使其等同于 responseTask.Wait()
?
最佳答案
你想错了。这是类内部发生的事情的伪版本。
class HttpClient : IDisposeable
{
private CancelationTokenSource _disposeCts;
public HttpClient()
{
_disposeCts = new CancelationTokenSource();
}
public Task<HttpResponseMessage> GetAsync(string url)
{
return GetAsync(url, CancellationToken.None);
}
public async Task<HttpResponseMessage> GetAsync(string url, CancelationToken token)
{
var combinedCts =
CancellationTokenSource.CreateLinkedTokenSource(token, _disposeCts.Token);
var tokenToUse = combinedCts.Token;
//... snipped code
//Some spot where it would good to check if we have canceled yet.
tokenToUse.ThrowIfCancellationRequested();
//... More snipped code;
return result;
}
public void Dispose()
{
_disposeCts.Cancel();
}
//... A whole bunch of other stuff.
}
重要的是当你退出
using
block 内部取消 token 被取消。在您的第一个示例中,任务尚未完成,所以
tokenToUse
如果 ThrowIfCancellationRequested()
现在会抛出被称为。在您的第二个示例中,任务已经完成,因此取消内部 token 的行为对返回的任务没有影响,因为它已经达到完成状态。
这就像问为什么这会导致任务被取消。
using (var client = new HttpClient())
{
var cts = new CancellationTokenSource()
var responseTask = client.GetAsync(urlToInvoke, cts.Token);
cts.Cancel();
}
但这并不
using (var client = new HttpClient())
{
var cts = new CancellationTokenSource()
var responseTask = client.GetAsync(urlToInvoke, cts.Token);
Task.Delay(5000).Wait()
cts.Cancel();
}
关于c# - 不等待 HttpClient 使用时会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25431291/