任务正在运行完成,即使它没有完成

时间:2017-11-10 15:26:57

标签: c# multithreading asynchronous concurrency prism

我遇到了一个问题,我似乎无法弄清楚为什么它似乎没有正常等待。

我有一个异步的递归文件副本,如下所示:

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();
    }

运行调试器时,它认为Task已运行完成。然而,这似乎并非如此,因为该方法中的Progress报告器减去了要复制的剩余文件总数,这些文件绑定到ViewModel。

ResetStats方法将剩余文件,剩余大小和当前日志设置为0.

但是,由于递归副本仍在发生,即使它表示任务已完成,它会导致我的UI进入负数。

我修复它的唯一方法是将递归包装到Task.Run中,但在那时我没有尝试异步地进行它。

我对这里发生的事情的最好猜测是与事件处理程序的异步void有关,但不确定如何解决它,因为命令是空的。

1 个答案:

答案 0 :(得分:1)

问题在于IProgress正在刷新UI以至于阻止了UI线程,导致await无法正常运行。在结果修复问题后添加延迟。

需要使用计时器或反应方法来修复它,而不是使用创可贴修复。