【发布时间】:2016-06-27 21:12:39
【问题描述】:
我正在开发一个内部备份程序,该程序利用 .NET 4.5 的 ZipArchive 和 ZipFile 类。到目前为止,我已经成功地压缩了不同大小和内容的文件夹,但是当压缩一个大文件夹时,UI 会冻结,直到所有备份都完成。我一直在谷歌和 SO 上寻找解决方案,但到目前为止还没有运气。
这是我启动后台线程的调用:
Dispatcher.Invoke(() =>
{
var result = BackupFolder(b1.Tag.ToString(), b1.Name);
Log = result.Result ? new BackupLog(string.Format("Finished zipping '{0}.zip'", b1.Name)) : new BackupLog(string.Format("Error zipping '{0}.zip'", b1.Name));
}, DispatcherPriority.Background);
这是它调用的方法:
private async Task<bool> BackupFolder(string path, string folderName)
{
try
{
var zipPath = string.Format("{0}{1}.zip", _backupPath.Backslash(), folderName);
Log = new BackupLog(string.Format("Starting zipping '{0}.zip'", folderName));
if (File.Exists(zipPath)) // ZIP already exists, let's update the contents
{
using (var existingZip = new FileStream(zipPath, FileMode.Open))
{
using (var archive = new ZipArchive(existingZip, ZipArchiveMode.Update))
{
foreach (var file in Directory.GetFiles(path))
{
if (archive.Entries.Any(a => a.FullName.Equals(Path.GetFileName(file)))) // Check if current file exists in the ZIP
{
var zipArchiveEntry =
archive.Entries.First(a => a.FullName.Equals(Path.GetFileName(file)));
if (zipArchiveEntry != null) zipArchiveEntry.Delete(); // Remove existing file from ZIP
}
archive.CreateEntryFromFile(file, Path.GetFileName(file));
}
}
}
}
else // ZIP does not exist, let's create it
{
ZipFile.CreateFromDirectory(path, zipPath);
}
return await Task.FromResult(true);
}
catch (Exception ex)
{
Debugger.Break();
}
return await Task.FromResult(false);
}
我尝试过使用Task.Run()、创建BackgroundWorker 以及可能我忘记尝试让UI 在后台压缩时保持交互性的其他几件事。
有什么建议吗?谢谢。
【问题讨论】:
-
result.Result,永远不要组合 asnyc/await 和.Result或.Wait()。此外,我在您的异步函数中看到的唯一await是await Task.FromResult(true);或 `await Task.FromResult(false);`,这对您没有任何作用。没有代码在后台线程上运行。同样Dispatcher.Invoke将代码放在 UI 线程上,它只是等待一段时间再将其放在那里。 -
感谢斯科特的信息。我过去用 WinForms 完成了线程,但 WPF 有点令人困惑。明天我要再试一次;我的大脑厌倦了今天看代码。
-
摆脱所有 async/await 的东西,摆脱 dispacter,然后只需执行
var result = await Task.Run(() => BackupFolder(b1.Tag.ToString(), b1.Name);并标记调用函数async
标签: c# wpf multithreading .net-4.5