【发布时间】:2017-11-10 15:26:56
【问题描述】:
我遇到了一个问题,我似乎无法弄清楚为什么它似乎没有正确等待。
我有一个异步的递归文件副本,如下所示:
public async Task CopyFiles(string source, string destination)
{
if (!Directory.Exists(destination))
{
Directory.CreateDirectory(destination);
}
var info = new DirectoryInfo(source);
foreach (var file in info.EnumerateFiles())
{
Progress.Report(new Counter { Files = 1, FileSize = file.Length, Log = $"Copying file {file.Name}" });
try
{
var newpath = Path.Combine(destination, file.Name);
if (File.Exists(newpath) && File.GetLastWriteTime(newpath) == file.LastWriteTime)
{
continue;
}
using (FileStream reader = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
{
using (FileStream writer = new FileStream(newpath, FileMode.Create, FileAccess.ReadWrite))
{
await reader.CopyToAsync(writer);
}
}
File.SetLastAccessTime(newpath, file.LastAccessTime);
File.SetLastWriteTime(newpath, file.LastWriteTime);
File.SetAttributes(newpath, file.Attributes);
}
catch
{
}
}
foreach (var directory in info.EnumerateDirectories())
{
try
{
await CopyFiles(directory.FullName, $"{destination}\\{directory.Name}");
}
catch
{
}
}
该方法在 Prism 中使用 DelegateCommand 调用
private async Task RestoreFiles()
{
var progress = GetProgressReporter();
var recursion = new Recursion(progress, Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
await recursion.CopyFiles(@"\\800CRBackup\Backups\Profiles\Beta\" + $"{Environment.UserName}", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)));
ResetStats();
}
运行调试器时,它认为任务已经运行完成。然而,情况似乎并非如此,因为该方法中的进度报告器减去绑定到 ViewModel 的剩余要复制的总剩余文件。
ResetStats 方法将剩余文件、剩余大小和当前日志设置为 0。
但由于递归副本仍在发生,即使它说任务已完成,它会导致我的 UI 进入负数。
我修复它的唯一方法是将递归包装到 Task.Run 中,但那时我没有必要尝试异步执行它。
我对这里发生的事情的最佳猜测是与事件处理程序中的 async void 有关,但不确定如何解决它,因为命令是 voids。
【问题讨论】:
-
您是否遇到了一些您未在 catch 中处理的错误?在这种情况下,异步并没有什么可实现的,它可能最终会减慢应用程序的速度,因为您没有处理高并发。
-
如果您没有创建目录的权限,代码将什么也不做。
-
任务无异常完成,我还用try catch块包围它以抛出异常,也没有捕获到任何东西。
-
是的,我知道如果目录创建中没有可用的权限,代码将失败,但在这种情况下,我确实有权限。代码工作正常,唯一的问题是等待的任务在它真正完成之前完成。如果它也包含在新线程中的 Task.Run 中,它也可以正常工作。
-
我看不到任何东西
async void,也看不到事件,也看不到DelegateCommand...你能发布相关代码吗?
标签: c# multithreading asynchronous concurrency prism