【发布时间】:2014-04-18 19:07:11
【问题描述】:
我有一个 Windows 服务,它每三秒轮询一次远程 FTP 服务器。它检查目录中的文件,下载所有存在的文件,并在下载后删除这些文件。平均文件大小为 10 KB,很少会达到 100 KB 的范围。
偶尔(我没有注意到任何模式),WebClient 会抛出以下内容:
System.Net.WebException: The operation has timed out.
at System.Net.WebClient.OpenRead(Uri address)
它将为一个或多个文件执行此操作,通常是当时远程目录中的任何文件。它将无限期地继续这样做,在每个轮询间隔搅动“卡住”的文件。奇怪的是,当我停止/启动 Windows 服务时,“卡住”的文件会完美下载,并且轮询/下载会在很长一段时间内再次运行。这很奇怪,因为我是这样下载的:
private object _pollingLock = new object();
public void PollingTimerElapsed(object sender, ElapsedEventArgs e)
{
if(Monitor.TryEnter(_pollingLock);
{
//FtpHelper lists content of files in directory
...
foreach(var file in files)
{
using(var client = new WebClient())
{
client.Proxy = null;
using(var data = client.OpenRead(file.Uri)
{
//Use data stream to write file locally
...
}
}
//FtpHelper deletes the file
...
}
}
//Release the _pollingLock inside a finally
}
我假设为每个文件打开和关闭一个新连接(除非 .NET 在幕后做某事)。如果文件下载有问题,它将在下一个轮询间隔(3 秒内)重新进行重试。为什么重启服务会让一切正常?
我开始怀疑这个问题与缓存(文件或连接)有关。最近我尝试进入 Internet Explorer 并清除缓存。大约 30 秒左右后,所有下载的文件都没有重新启动服务。但是,下一批要到的文件又都挂了。我可能会尝试添加这样的一行:
client.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
或尝试禁用 KeepAlives,但我想在开始尝试随机的东西之前获得一些意见。
那么:是什么导致偶尔超时?为什么重启服务会起作用?为什么清除缓存有效?
更新
大约两周前,我制定了上述缓存策略和保持活动更改。从那以后,我刚刚获得了第一次超时。它似乎提高了频率,但遗憾的是,它仍在发生。
更新
根据要求,这就是我开始 Timer 的方式:
_pollingTimer.AutoReset = true;
_pollingTimer.Elapser += PollingTimerElapsed;
_pollingTimer.Interval = 10000;
_pollingTimer.Enabled = true;`
【问题讨论】:
-
您每三秒轮询一次服务器?哇。您是否考虑过安装该资源?
-
遗憾的是,我没有该选项,因为我无法控制服务器、数据源或下载机制的选择。不过,幸运的是,我是唯一一个轮询此服务器的人。我承认 3 秒是极端的,但我需要对这些数据进行低延迟。
-
也许你用尽了可用端口的数量:stackoverflow.com/a/1087525/578411
-
您是否启用了网络跟踪? msdn.microsoft.com/en-us/library/ty48b824(v=vs.110).aspx 你也检查了 DefaultConnectionLimit:msdn.microsoft.com/en-us/library/…
-
@Simon Mourier,过去几天我一直在调整
ServicePoint的值,正在等待看看效果如何。谢谢。
标签: c# .net ftp windows-services webclient