会发生什么异步code任务时,不等待 [英] What happens with asynchronous code when Tasks are not awaited
问题描述
由于code类似于
Task.Run(() =>
{
using (var client = new HttpClient())
{
var responseTask = client.GetAsync(urlToInvoke);
}
});
在这样的情况下,似乎 GetAsync
并没有实际操作。是任务取消之前完成,或者什么是真正回事?
In a situation like this, it appears that GetAsync
does not actually operate. Is the task canceled prior to completion or what is actually going on here?
现在,如果你改变的事情略有并插入
Now if you change things slightly and insert
Task.Run(() =>
{
using (var client = new HttpClient())
{
var responseTask = client.GetAsync(urlToInvoke);
Task.Delay(5000).Wait()
}
});
GetAsync
没有完全执行。这里发生了什么?为 Task.Delay
affinitizing本身相同任务就是里面的 responseTask
最终使这相当于 responseTask.Wait()
?
GetAsync
does execute completely. What is going on here? Is Task.Delay
affinitizing itself to the same Task that is inside responseTask
ultimately making this equivalent to responseTask.Wait()
?
推荐答案
您所想的是不正确的。这里是正在发生的事情在类中的伪版本。
You are thinking of it incorrectly. Here is pseudo version of what is happening inside the class.
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.
}
重要的是要看到的是,当你退出使用
A座内取消令牌将被取消。
The important thing to see is when you exit the using
block a internal cancelation token is canceled.
在你的第一个例子中的任务还没有完成呢等等 tokenToUse
现在会抛出,如果 ThrowIfCancellationRequested()
被称为。
In your first example the task had not finished yet so tokenToUse
would now throw if ThrowIfCancellationRequested()
was called.
在第二个例子中,任务已经完成了,以便消除内部令牌的行为对返回,由于它已经达到完成状态的任务没有影响。
In your second example the task had already finished so the act of canceling the internal token had no effect on the task that was returned due to it already reaching the completed state.
这就像问为什么这会导致任务被取消。
It is like asking why this causes the task to be canceled.
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();
}
这篇关于会发生什么异步code任务时,不等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!