C# 为什么CopyFileEx的FileUtilities.CopyFile包装器会干扰winforms?
我在这里使用CopyFileEx的C# 为什么CopyFileEx的FileUtilities.CopyFile包装器会干扰winforms?,c#,winforms,visual-studio-2010,file-copying,C#,Winforms,Visual Studio 2010,File Copying,我在这里使用CopyFileEx的FileUtilities.CopyFile包装器。我认为只有在复制文件之后才会调用CopyFileCallbackAction(我尝试复制一个大文件)。于是问了这个问题。但现在我发现它实际上被调用了很多次,但由于某种原因,它弄乱了我试图显示进度的表单——在复制完成之前表单不会得到更新。事实上,如果我尝试在所示的事件处理程序中运行它,那么在复制完成之前,表单中应该有按钮的空框。为什么会这样?您需要从后台线程调用CopyFileEx。此时,对CopyFileEx的
FileUtilities.CopyFile
包装器。我认为只有在复制文件之后才会调用CopyFileCallbackAction
(我尝试复制一个大文件)。于是问了这个问题。但现在我发现它实际上被调用了很多次,但由于某种原因,它弄乱了我试图显示进度的表单——在复制完成之前表单不会得到更新。事实上,如果我尝试在所示的事件处理程序中运行它,那么在复制完成之前,表单中应该有按钮的空框。为什么会这样?您需要从后台线程调用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时使用Invoke
或BeginInvoke
。这是因为更新UI的代码需要从UI线程运行。谢谢!我可以使用BackgroundWorker
吗?是的,这会很好地完成这项工作。事实上,我发现它不会阻塞,因为对回调方法的每次调用都让回调方法处理UI。缺少的只是一个this.Update()代码>。(请参阅:)它会阻止它,使其感觉在复制所有文件之前不会返回。如果您不使用工作线程,那么就不会抽取消息队列。