6

我有一个简单的 C# 系统托盘应用程序,用于System.Net.WebClient下载多个文件,每个文件的范围为 3-15MB。WebClient 正在通过 HTTPS 下载,我控制从中进行下载的服务器。文件通过直接路径从 Web 浏览器下载得很好,并且 WebClient 完全能够处理.DownloadString()来自该服务器的方法(即,将短文本文件下载到字符串)。

奇怪的是,在 24 小时内发生了三件事,我怀疑某种特定于机器的配置或缓存,但我想知道其他人可能知道WebClient's 的内幕,这可能会让他们冒险猜测:

  1. 开发机器#1 在调试模式下运行此代码并下载文件(称为 MegabyteFile1 和 MegabyteFile2)直到星期五都没有问题。下载最多需要 3-5 秒。
  2. 突然,1 号开发机器在周五下午停止下载 MegabyteFile1。行为如下:
    • WebClient.DownloadFile()无限期挂起
    • 文件 attargetFileFullPath已创建但有 0 个字节。
    • 主线程无限期阻塞。
    • 必须退出应用程序。
  3. 其他具有相同操作系统配置的开发机器可以正常运行代码并成功下载。
  4. 在 DevelopmentMachine1 上使用 Chrome 或 Internet Explorer 手动下载这些文件工作得很好,有和没有查询参数。
  5. 如果 Fiddler 正在运行, DevelopmentMachine1下载该文件(即使没有安装 Fiddler HTTPS 证书冒名顶替者)。换句话说,如果我尝试嗅探这台机器上的电线,一切正常。

下载代码的相关部分内容如下:

using (WebClient client2 = new WebClient())
{
  client2.DownloadFile(String.Format("{0}?{1}", thePath, queryParams), targetFileFullPath);
}

我已经在这个盒子上尝试了通常的系统管理员的东西:重新启动它,清除 Internet Explorer 缓存和临时目录等。

我知道我需要改变处理挂起下载的策略,因为我确信在现实世界中会有挂起的下载。但是,如果我不了解导致这种特定故障模式的原因,我不确定我会考虑所有极端情况。任何人都对发生的事情有足够的了解WebClient来冒险猜测为什么这台机器是“特殊的”?

谢谢!-詹姆士

4

4 回答 4

7

遇到同样的问题,但找到了另一种解决方案。这里相当复杂的讨论: http ://social.msdn.microsoft.com/Forums/en-US/a00dba00-5432-450b-9904-9d343c11888d/webclient-downloadstringasync-freeze-my-ui?forum=ncl

简而言之,问题在于 Web 客户端正在搜索代理服务器并挂起应用程序。以下解决方案有帮助:

WebClient webClient = new WebClient();
webClient.Proxy = null;
... Do whatever else ...
于 2014-04-05T20:51:16.737 回答
4

在屏幕上敲了几个小时,与WireShark进行了愉快的会话以及与Fiddler进行了几次单独的会话之后,我找到了答案。在这里分享,以防其他人有同样的问题。

事实证明,如果对象没有正确 d ,任何使用HttpWebRequest先验都会导致这种行为。无论您是创建多个还是对象。他们都会失败。WebResponse.Close()WebClientHttpWebRequest

线索来自以下观察:观察 WireShark 中的 TCP 来回传输,很明显没有任何内容被发送到第二个请求(失败的请求)的服务器。为什么这在 Fiddler 运行时有效,但在不运行时无效?我怀疑 Fiddler 正在“玩得很好”并强行关闭连接。

于 2013-08-12T23:39:10.147 回答
4

我遇到了类似的问题,当某些 Web 请求之前发生时,WebClient.DownloadFile 会超时。在毫无结果地搜索未正确关闭的 Web 请求响应(使用此方法)后,我遇到了ServicePointManager.DefaultConnectionLimit属性。在我的应用程序开始时将其设置得更高为我解决了这个问题,如下所示:

ServicePointManager.DefaultConnectionLimit = 20

于 2017-02-05T22:20:42.210 回答
0

至于我,DownloadFileTaskAsync在命令行应用程序(在 F# 中实现)中使用该方法时遇到了问题:

let task = webClient.DownloadFileTaskAsync (uri, Path.GetFileName(uri.LocalPath))
task.Wait()

不知道这里有什么坏处,但切换到使用 F# 异步工作流解决了这个问题:

async {
    let task = webClient.DownloadFileTaskAsync (uri, Path.GetFileName uri.LocalPath)
    do! Async.AwaitTask task
} |> Async.RunSynchronously
于 2019-09-21T09:30:04.800 回答