【问题标题】:Why is FileUtilities.CopyFile wrapper for CopyFileEx interfering with winforms?为什么 CopyFileEx 的 FileUtilities.CopyFile 包装器会干扰 winforms?
【发布时间】:2012-01-13 16:00:21
【问题描述】:

我在 http://msdn.microsoft.com/en-us/magazine/cc163851.aspx 使用 CopyFileEx 的 FileUtilities.CopyFile 包装器。我认为CopyFileCallbackAction 直到文件被复制后才会被调用(我尝试过复制一个大文件)。因此问了这个How do I get CopyFileEx to report back so I can cancel a file copy operation? 问题。但是现在我发现它实际上被调用了很多次,但由于某种原因,它弄乱了我试图显示进度的表单——在复制完成之前表单不会更新。事实上,如果我尝试在Shown 事件处理程序中运行它——表单有空框,按钮应该是——直到复制完成。这是为什么呢?

【问题讨论】:

    标签: c# winforms visual-studio-2010 file-copying


    【解决方案1】:

    您需要从后台线程调用CopyFileEx。目前对CopyFileEx 的调用正在阻塞UI 线程。这就是 UI 不更新的原因。

    回调动作确实被重复调用了。这样您就可以向用户报告长时间运行的文件操作的进度。

    需要明确的是,当您致电 CopyFileEx 时会发生这种情况:

    Enter CopyFileEx
      Start copying
      Call your callback
      Continue copying
      Call your callback
      ....
    Return from CopyFileEx
    

    在文件复制的整个过程中,执行线程忙于复制文件而不是抽出消息队列。尽管这是 WinForms 而不是 Win32,但 WinForms 是围绕标准 Win32 GUI 框架的相对轻量级的包装器。您的消息队列需要定期维护,因此所有长时间运行的任务都需要从 UI 线程中运行。

    最后一点:请记住,当您收到进度回调时,您需要在更新任何 UI 时使用 InvokeBeginInvoke。这是因为更新 UI 的代码需要从 UI 线程运行。

    【讨论】:

    • 谢谢!我可以为此使用BackgroundWorker 吗?
    • 是的,这会很好地完成这项工作。
    • 实际上,我发现它不会阻塞,因为每次调用回调方法都会让回调方法处理 UI。所缺少的只是一个 this.Update(); 。 (见:stackoverflow.com/questions/8405254/…
    • 它阻止了它在复制所有文件之前不会返回的感觉。如果您不使用工作线程,那么您将不会抽取消息队列。
    猜你喜欢
    • 1970-01-01
    • 2019-09-25
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 2011-11-22
    相关资源
    最近更新 更多