为什么CopyFileEx的FileUtilities.CopyFile包装器会干扰winforms?

时间:2011-12-05 23:23:00

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

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

1 个答案:

答案 0 :(得分:9)

您需要从后台线程中调用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的代码。