给定的代码类似于
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
块时取消内部取消令牌。
在您的第一个示例中,任务尚未完成,因此tokenToUse
如果ThrowIfCancellationRequested()
被调用将立即引发。
在您的第二个示例中,任务已经完成,因此取消内部令牌的操作对由于已达到完成状态而返回的任务没有影响。
这就像问为什么这导致任务被取消。
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();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句