据我所知,没有办法知道它特别是发生了超时.我不是在寻找合适的地方,还是我错过了更大的东西?
string baseAddress = "http://localhost:8080/";
var client = new HttpClient() 
{ 
    BaseAddress = new Uri(baseAddress), 
    Timeout = TimeSpan.FromMilliseconds(1) 
};
try
{
    var s = client.GetAsync("").Result;
}
catch(Exception e)
{
    Console.WriteLine(e.Message);
    Console.WriteLine(e.InnerException.Message);
}
返回:
发生了一个或多个错误.
任务被取消了.
HttpClient有一个内置超时功能(尽管都是异步的,即超时可以被认为是与http请求功能正交,因此可以由通用异步实用程序处理,但是除此之外)当超时启动时,它会抛出一个TaskCanceledException(包含在内) a AggregateException).
TCE包含CancellationToken等于的CancellationToken.None.
现在,如果我提供HttpClient了CancellationToken我自己的一个并使用它来取消操作完成(或超时),我得到完全相同TaskCanceledException,再次使用CancellationToken.None.
通过仅查看抛出的异常,还有一种方法可以确定超时是否取消了请求,而不必让我自己CancellationToken可以访问检查异常的代码?
PS这可能是一个错误,并CancellationToken以某种方式错误地修复CancellationToken.None?在取消使用自定义CancellationToken的情况下,我希望TaskCanceledException.CancellationToken等于该自定义令牌.
编辑  
为了使问题更加清晰,通过访问原始文件CancellationTokenSource,很容易区分超时和用户取消:
origCancellationTokenSource.IsCancellationRequested == true
CancellationToken从异常中获取但是给出了错误的答案:
((TaskCanceledException)e.InnerException).CancellationToken.IsCancellationRequested == false
这是一个最小的例子,由于受欢迎的需求:
public void foo()
{
    makeRequest().ContinueWith(task =>
    {
        try
        {
            var result = task.Result;
            // do something with the result;
        }
        catch (Exception e)
        {
            TaskCanceledException innerException = e.InnerException as TaskCanceledException;
            bool …我有一些代码通过调用许多其他服务来验证某些数据.我并行启动所有调用,然后等到其中至少一个完成.如果任何请求失败,我不关心其他调用的结果.
我打电话,HttpClient我已经通过了HttpMessageHandler一个记录.实质上:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    HttpResponseMessage response = null;
    try
    {
        response = await base.SendAsync(request, cancellationToken);
    }
    catch (OperationCanceledException ex)
    {
        LogTimeout(...);
        throw;
    }
    catch (Exception ex)
    {
        LogFailure(...);
        throw;
    }
    finally
    {
        LogComplete(...);
    }
    return response;
}
当我取消请求时,我遇到麻烦的部分没有.当我取消请求时,我是故意这样做的,所以我不希望它被记录为超时,但是在取消和实际超时之间似乎没有任何区别.
反正有没有完成这个?
编辑: 我需要澄清一下这一点.并行调用的服务是使用超时传递CancellationTokens:
var ct = new CancellationTokenSource(TimeSpan.FromSeconds(2));
因此,当服务器响应时间超过两秒时,我得到一个OperationCanceledException,如果我手动取消令牌源(比如因为另一台服务器在1秒后返回错误),那么我仍然得到一个OperationCanceledException.理想情况下,我将能够看到CancellationToken.IsCancellationRequested以确定它是否被取消,由于超时,而不是明确要求被取消,但现在看来,你得到相同的值,而不管怎么就被取消了.
c# http cancellation cancellationtokensource dotnet-httpclient
当我创建一个默认的CancellationToken,我可以在该调试器中看到CancellationToken有一个CancellationTokenSource与它存储在私有关联的m_source领域:

我想知道如何对于结构default关键字"将返回结构的每个成员初始化为零或取决于它们是值还是引用类型"并且CancellationTokenSource是引用类型.
CancellationToken确实有2个构造函数设置这个字段然而它们是不相关的,因为default(CancellationToken)不调用构造函数和new CancellationToken()(它具有完全相同的行为)不会调用构造函数,因为结构不能有无参数构造函数(尚未).