等待 HttpClient.GetStreamAsync 永远等待[关闭]

Posted

技术标签:

【中文标题】等待 HttpClient.GetStreamAsync 永远等待[关闭]【英文标题】:Await on HttpClient.GetStreamAsync Awaits Forever [closed] 【发布时间】:2021-02-15 13:01:44 【问题描述】:

问题是,当我将await 放在HttpClient.GetStreamAsync() 之前时,它不会返回任何内容,Visual Studio 会自行挂起,只要我决定停止调试,就不会返回任何内容。当我尝试使用.GetAwaiter().GetResult() 时,它会提示我在this 问题上显示的错误,不幸的是没有产生任何解决方案。 这些错误会导致什么结果? TLS 问题是不确定的。网络团队确保我试图从中获取结果的 api 的地雷请求没有被阻止,并且对方确认他们也没有阻止我们的请求。可以确认这一点,因为 Postman 请求与 api 配合得很好。我使用了HttpClientWebRequest 提示同样的错误。等待甚至不会导致错误,它只是闲置......

为什么我会遇到这个问题?我怎样才能克服它?任何帮助表示赞赏。

(我尝试过的代码和solutions可以在this我的问题中找到。

【问题讨论】:

所有错误都指向服务器的问题。您无法在客户端解决此问题。您只能为您的操作添加超时,这样您就不会永远等待。顺便说一句,阻止异步操作是个坏主意。通过允许过时的算法来削弱 TLS 加密也是如此 @PanagiotisKanavos,我创建了一个工作正常的 .Net Framework 4.7.2 项目和一个 .Net Core 3.1 项目。一点都不麻烦。但是在 .Net Framework 4.7.2 上运行的项目不知何故无法按预期工作。此问题不可能是服务器问题。 创建一个新的 HttpClient 实例也很糟糕,这个类是线程安全的并且意味着可以重用。否则,您最终会耗尽所有可用的套接字,而这可能会导致问题。检查You're using HttpClient wrong and its destabilizing your software。 您没有提供足够的信息,所以人们只能猜测出了什么问题。特别是在 this 问题中。 HttpClient 没有损坏。如果有流,GetStreamAsync 会打开它。所以要么服务器被阻塞,要么客户端代码以某种方式最终阻塞了自己。 HttpClient 没有损坏。您在原始问题中发布的代码虽然有严重的错误 - 阻止异步调用、削弱安全性、创建新的 HttpClient 实例并可能耗尽可用的套接字 我想Postman 可以使用您的公司代理设置,而.Net 应用程序可能会尝试直接建立它。看起来像是您的环境有问题,而不是代码。 【参考方案1】:

对您的问题的简短回答是“您的服务器没有返回所有数据,并且您确实要求方法等待”。但这没有帮助。

您可能希望 HttpClient 获取异步方法超时。下面的代码是如何做到这一点的人为示例。下面是代码的作用:

    创建了一个 CancellationToken 源,它将在 500 毫秒后发出 CancellationToken 已取消的信号。 我获得了 Google 搜索页面的默认登录页面。我只使用 Geta 同步而不是 GetstreamAsync,因为我想不出我不必自己编写代码的流响应的来源。虽然是同一个校长。在我的网络上,500 毫秒的超时时间已经足够了,所以我收到一条消息“响应代码 = OK”。 如果我将 500 毫秒更改为 10 毫秒,响应不会在时间用完之前完成,我会收到“任务已取消”的消息。

所以,当您说“等待”时,它的真正意思是“在这里等到我调用的方法完成,除非我在此之前取消等待。另外请记住,根据您的需要,可能有各种 CancellationTokenSources。这只是一个例子。

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace cancel

    class Program
    
        static async Task Main(string[] args)
        
            CancellationTokenSource cancellationSource = new CancellationTokenSource(new TimeSpan(0,0,0,0,5000)); //Succeeds
            //CancellationTokenSource cancellationSource = new CancellationTokenSource(new TimeSpan(0,0,0,0,10)); //Fails
            CancellationToken cancellationToken = cancellationSource.Token;

            var client = new HttpClient();
            try
            
                var result = await client.GetAsync("https://www.google.com",cancellationToken);
                Console.WriteLine($"Response code = result.StatusCode");
            
            catch(Exception ex)
            
                Console.WriteLine(ex.Message);
            

        
    

【讨论】:

感谢您对限制等待时间的建议。这肯定会对我有很大帮助。您是否知道 .Net Framework 4.7.2 Web API 项目如何无法使用HttpClient 获取某些内容,但在使用相同网络的同一台机器上,.Net Core 3.1 控制台应用程序获取相同的内容查询就好了?此外,常规的 .Net Framework 4.7.2 控制台应用程序与 .Net Core 3.1 一样好。在Web API项目上继承的ApiController会导致这个问题吗? 我需要更多信息,但我可以告诉您,.Net Framework HttpClient 的工作方式和 .NET Core HttpClient 的工作方式几乎没有区别。如果我不得不猜测,我会说 4.7.2 代码中存在错误。 我会和网络团队谈谈,看看网络是否会导致任何错误。他们说他们修复了它,因为我使用来自同一个查询的其他项目/工具得到了好的结果,他们只是说这与网络无关:/我希望他们错了,因为我对代码的可能方式一无所知有错误或错误。感谢您的帮助:)

以上是关于等待 HttpClient.GetStreamAsync 永远等待[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

selenium强制等待,隐式等待,显式等待

selenium中的显示等待,隐示等待,强制等待

sql server等待类型

selenium中的三种等待方式(显示等待WebDriverWait()隐式等待implicitly()强制等待sleep())---基于python

selenium显示等待和隐式等待的区别

selenium 显示等待和隐式等待哪个更好