使用 Backgroundworker 和 byte[] 在后台下载文件
Downloading Files in Background with Backgroundworker and byte[]
我想使用 Backgroundworker 从网络服务器下载一些文件。我已经有了这个
WebClient req = new WebClient();
byte[] pbo = request.DownloadData(PathOnWebserver);
FileStream dwn = File.Create(LocalPath);
dwn.Write(pbo, 0, pbo.Length);
dwn.Close();`
在我的第一次尝试中,运行在 WindowsForm 应用程序中成功。
现在我 运行 在 Wpf 应用程序中使用了相同的代码,它抛出了 OutOfMemoryException。
所以我用谷歌搜索了这个问题,但在下载完整文件之前我没有找到存储数据的解决方案。
我需要这个,因为稍后我必须处理这个文件,如果我有损坏的数据,比如如果我关闭应用程序,我可以将它们扔进垃圾桶。
是否有一种简单的方法来获得类似于 运行 的代码,以保证数据完整?
使用 Task Parallel Library (TPL) 提供的 Task
class 可能会更幸运。下面是一个可能的解决方案的简短模型。您显然需要实例化下载数据时使用的变量,例如 LocalPath
和 PathOnWebserver
.
// Call this method to start the download
private void DownloadData()
{
// Create a TaskFactory on the current Thread; the UI thread
TaskFactory UITaskFactory =
new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
// Create and start a Task that will download the data
var DoDownloadTake = Task.Factory.StartNew(() =>
{
Boolean success = false;
try
{
WebClient wc = new WebClient();
byte[] pbo = wc.DownloadData(PathOnWebserver);
FileStream dwn = File.Create(LocalPath);
dwn.Write(pbo, 0, pbo.Length);
dwn.Close();
success = true;
}
catch(Exception ex){} // Handles this however you'd like to.
// Call a method on the UI thread to notify us the download completed
UITaskFactory.StartNew(() => DataFinishedDownloading(success));
});
}
// Once the data is finished downloading this method will be called
private void DataFinishedDownloading(Boolean success)
{
if(success)
;// Do something with data at LocalPath
else
;// Download failed
}
就这样
req.DownloadFile(PathOnWebserver, TempLocalPath);
File.Move(TempLocalPath, LocalPath);
如果 TempLocalPath 与 LocalPath 在同一驱动器上,则 Move 是原子的,因为它只是执行重命名。如果您遇到故障,您只需在启动时将临时文件丢弃即可。 Chrome 和 Firefox 等程序通过在文件仍在下载时将 .partial
添加到文件名来执行此确切方法,然后在完成后重命名。
我想使用 Backgroundworker 从网络服务器下载一些文件。我已经有了这个
WebClient req = new WebClient();
byte[] pbo = request.DownloadData(PathOnWebserver);
FileStream dwn = File.Create(LocalPath);
dwn.Write(pbo, 0, pbo.Length);
dwn.Close();`
在我的第一次尝试中,运行在 WindowsForm 应用程序中成功。 现在我 运行 在 Wpf 应用程序中使用了相同的代码,它抛出了 OutOfMemoryException。 所以我用谷歌搜索了这个问题,但在下载完整文件之前我没有找到存储数据的解决方案。 我需要这个,因为稍后我必须处理这个文件,如果我有损坏的数据,比如如果我关闭应用程序,我可以将它们扔进垃圾桶。
是否有一种简单的方法来获得类似于 运行 的代码,以保证数据完整?
使用 Task Parallel Library (TPL) 提供的 Task
class 可能会更幸运。下面是一个可能的解决方案的简短模型。您显然需要实例化下载数据时使用的变量,例如 LocalPath
和 PathOnWebserver
.
// Call this method to start the download
private void DownloadData()
{
// Create a TaskFactory on the current Thread; the UI thread
TaskFactory UITaskFactory =
new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
// Create and start a Task that will download the data
var DoDownloadTake = Task.Factory.StartNew(() =>
{
Boolean success = false;
try
{
WebClient wc = new WebClient();
byte[] pbo = wc.DownloadData(PathOnWebserver);
FileStream dwn = File.Create(LocalPath);
dwn.Write(pbo, 0, pbo.Length);
dwn.Close();
success = true;
}
catch(Exception ex){} // Handles this however you'd like to.
// Call a method on the UI thread to notify us the download completed
UITaskFactory.StartNew(() => DataFinishedDownloading(success));
});
}
// Once the data is finished downloading this method will be called
private void DataFinishedDownloading(Boolean success)
{
if(success)
;// Do something with data at LocalPath
else
;// Download failed
}
就这样
req.DownloadFile(PathOnWebserver, TempLocalPath);
File.Move(TempLocalPath, LocalPath);
如果 TempLocalPath 与 LocalPath 在同一驱动器上,则 Move 是原子的,因为它只是执行重命名。如果您遇到故障,您只需在启动时将临时文件丢弃即可。 Chrome 和 Firefox 等程序通过在文件仍在下载时将 .partial
添加到文件名来执行此确切方法,然后在完成后重命名。