我正在编写一个管理游戏mod /插件库的应用程序。每隔一段时间,其中一个mod就有一个可用的更新,并且使用WebClient.DownloadFileAsync()下载新版本,通过读取WebRequest响应中的Content-Disposition来检索文件名。
当有两个或更多更新可用时,第一个下载完全正常,但是当您尝试下载第二个文件而没有重新启动应用程序WebClient冻结时,将使用检索到的名称创建该文件,但包含0个字节,而不包含DownloadProgressChanged或者触发了DownloadFileCompleted事件。
如果我不尝试检索原始文件名,只是在本地给它们命名,那么WebClient就不会冻结。但我需要原始文件名。
我能做些什么来避免这个问题,同时还能检索原始文件名吗?
private void Download(string url, string downloadDirectory)
{
WebClient wc = new WebClient();
string filename = FilenameFromURL(url);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgress);
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadComplete);
wc.DownloadFileAsync(new Uri(url), downloadDirectory + filename);
}
private string FilenameFromURL(string url)
{
return new ContentDisposition(WebRequest.Create(url).GetResponse().Headers["Content-Disposition"].ToString()).FileName;
}
private void DownloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
downloadProgressBar.Value = e.ProgressPercentage;
}
private void DownloadComplete(object sender, AsyncCompletedEventArgs e)
{
// ...
}
答案 0 :(得分:1)
我遇到了同样的问题。经过数小时和数小时后,我发现问题出在一条没有处理的溪流中。我用它来检查web目录中存在文件的天气。
private bool WebFileExists(string url)
{
bool exists = true;
try
{
using (WebClient testClient = new WebClient())
{
testClient.Credentials = new NetworkCredential(_userName, _password);
Stream stream = testClient.OpenRead(url);
stream.Dispose();
}
}
catch
{
exists = false;
}
return exists;
}
答案 1 :(得分:0)
实际上我复制了你在WPF客户端中使用的相同代码。我从第一个文件中复制了这个问题。我发现本地创建了一个0字节长度的文件但没有内容。
在我的情况下,我添加的解决方案是设置用户凭据,之后我可以重复下载多个文件(踩下以前的下载)。
我添加了这一行:wc.Credentials = CredentialCache.DefaultCredentials;
private void Download(string url, string downloadDirectory, string fileName)
{
WebClient wc = new WebClient();
wc.Credentials = CredentialCache.DefaultCredentials;
wc.DownloadProgressChanged += DownloadProgress;
wc.DownloadFileCompleted += DownloadComplete;
wc.DownloadFileAsync(new Uri(url), downloadDirectory + fileName);
}
答案 2 :(得分:0)
我设法通过传递通过EventHandler参数下载文件的WebClient实例然后使用它来获取原始文件名来解决问题,而不是使用它的单独实例来检索文件名。
感谢this question帮助我找出解决方案。
使用此解决方案,因为在文件下载之前我找不到原始文件名,所以我为其分配了一个临时名称,并在AsyncCompletedEventHandler中完成下载后重命名。
private void Download(string url, string downloadDirectory)
{
WebClient wc = new WebClient();
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgress);
wc.DownloadFileCompleted += new AsyncCompletedEventHandler((sender, e) => DownloadComplete(sender, e, wc));
wc.DownloadFileAsync(new Uri(url), downloadDirectory + "temp");
}
private void DownloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
downloadProgressBar.Value = e.ProgressPercentage;
}
private void DownloadComplete(object sender, AsyncCompletedEventArgs e, WebClient wc)
{
string filename = new ContentDisposition(wc.ResponseHeaders["Content-Disposition"].ToString()).FileName;
if (File.Exists(downloadDirectory + "temp"))
{
if (File.Exists(downloadDirectory + filename))
File.Delete(downloadDirectory + filename);
File.Move(downloadDirectory + "temp", downloadDirectory + filename);
}
// ...
}