c# - 不等待 HttpClient 使用时会发生什么

标签 c# .net asynchronous task-parallel-library dotnet-httpclient

给定代码类似于

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/

相关文章:

c# - "=>"是什么意思?

java - Servlet 3.0 测试查询中的异步属性

node.js - Mongoose 异步/等待查找然后编辑并保存?

c# - 我的通用 Future 实现是否应该有一个 Completed 事件?

c# - 在 .NET 中动态添加引用

c# - 我需要使用MS Debug Diagnostic Tool来分析CPU使用率较高的C#应用​​程序的帮助

c# - 比较类的两个实例

.NET ORM 需要虚拟,不能处理密封?

c# - 为什么我在 listView1 上没有属性项?

c# - 如何一次读取一个 csv 文件并替换/编辑某些行?