42

我正在测试一个遇到一些问题的端点。

我只是HttpClient在一个每小时执行一个请求的循环中使用。

var httpClient = new HttpClient();
var message = httpClient.GetAsync(url).Result;
Console.WriteLine(message.StatusCode);

偶尔我会遇到这个异常:

System.Net.Http.HttpRequestException:发送请求时出错。---> System.Net.WebException:无法解析远程名称:'xxx'

经验是,异常之后,URL就可以访问了。在浏览器中,您只需刷新页面,一切都很好。

我仍然没有收到用户的任何报告,所以我想知道这是否只是一个本地问题,但可以使用一些信息来帮助诊断。

有没有办法检查无法解析远程名称是由 DNS 问题还是由异常引起的 Web 服务器问题引起的?我可以从中获取更多信息,HttpCLient还是需要更高级的诊断工具?

4

4 回答 4

45

可能是由本地网络连接问题引起的(但也可能是 DNS 错误)。不幸HResult的是,它是通用的,但是您可以确定捕获HttpRequestException并检查的确切问题InnerException:如果是,WebException那么您可以检查WebException.Status属性,例如WebExceptionStatus.NameResolutionFailure应该指示 DNS 解析问题。


它可能会发生,你无能为力。

我建议始终使用try/catch块将(与网络相关的)代码包装在一个循环中(对于其他易错操作也如此建议)。处理已知异常,稍等片刻(比如 1000 毫秒),然后重试(比如 3 次)。仅当始终失败时,您才能退出/向用户报告错误。像这样的非常原始的例子:

private const int NumberOfRetries = 3;
private const int DelayOnRetry = 1000;

public static async Task<HttpResponseMessage> GetFromUrlAsync(string url) {
    using (var client = new HttpClient()) {
        for (int i=1; i <= NumberOfRetries; ++i) {
            try {
                return await client.GetAsync(url); 
            }
            catch (Exception e) when (i < NumberOfRetries) {
                await Task.Delay(DelayOnRetry);
            }
        }
    }
}
于 2014-07-29T11:32:24.193 回答
10

I had a similar issue when trying to access a service (old ASMX service). The call would work when accessing via an IP however when calling with an alias I would get the remote name could not be resolved.

Added the following to the config and it resolved the issue:

<system.net>
    <defaultProxy enabled="true">
    </defaultProxy>
</system.net>
于 2018-02-07T13:59:57.427 回答
3

打开位于 **C:\windows\system32\drivers\etc**的主机文件。

hosts文件是干什么用的?

在此文件末尾添加以下内容:

YourServerIP YourDNS

例子:

198.168.1.1 maps.google.com

于 2018-07-12T08:46:07.837 回答
0

这个问题肯定与c#的HttpClient有关。该客户端旨在重用它。因为在你处理 HttpClient 后套接字并没有直接关闭。这篇博文( https://www.nimaara.com/beware-of-the-net-httpclient/ )提供了很好的解释。

您必须处理 DNS 查找表已过时的情况。在博客文章中,您还可以找到如何执行此操作的信息。

ServicePointManager.FindServicePoint(endpoint).ConnectionLeaseTimeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;

ServicePointManager.DnsRefreshTimeout = (int)1.Minutes().TotalMilliseconds;

于 2021-06-22T05:47:41.203 回答