使用CopyFileEx完成复制文件(带进度指示器)后,主窗体是否被冻结?

时间:2013-05-09 12:00:38

标签: c# multithreading winforms winapi pinvoke

我有一个主表单,此表单有一个单击按钮,将显示带有进度条的复制窗口。我使用线程来执行复制作业,但是在完成复制(文件被复制好并且复制窗口关闭)后,主窗体被冻结(窗体上的控件似乎不是交互式的)。任务管理器显示没有太多工作(0%)。这里有一些奇怪的东西。以下是复制对话的代码,请参阅:

public partial class FileCopier : Form
{
    [DllImport("Kernel32")]
    private extern static int CopyFileEx(string source, string destination, CopyProgressRoutine copyProgress, int data, ref int cancel, int flags);
    private delegate int CopyProgressRoutine(long totalBytes, long bytesCopied, long streamSize, long streamCopied, int streamNumber, int callBackReason, int source, int destination, int data);
    public FileCopier()
    {
        InitializeComponent();            
    }
    #region private members
    int cancel;
    int copyFinished = -1;                
    #endregion
    #region public methods
    public void Copy(string source, string destination)
    {            
        CoreHandling(source, destination);            
    }
    public void MoveFile(string source, string destination)
    {
        CoreHandling(source, destination);
        if (cancel == 0)//If there is no canceling action
        {
            //Delete the source file
            File.Delete(source);
        }            
    }
    #endregion
    #region private methods
    private void CoreHandling(string source, string destination)
    {
        startTime = DateTime.Now;
        ThreadStart ths = delegate
        {
            CopyFileEx(source, destination, UpdateCopyProgress, 0, ref cancel, 1);
        };
        new Thread(ths).Start();
        ShowDialog();
        while (copyFinished == -1)
        {
            Thread.Sleep(10);
        }
        copyFinished = -1;
    }
    private int UpdateCopyProgress(long totalBytes, long bytesCopied, long streamSize, long streamCopied, int streamNumber, int callBackReason, int source, int destination, int data)
    {
        if (InvokeRequired)
        {                
            Invoke(new CopyProgressRoutine(UpdateCopyProgress), totalBytes, bytesCopied, streamSize, streamCopied, streamNumber, callBackReason, source, destination, data);
        }
        else
        {
            int percentage = (int)(((double)bytesCopied / totalBytes) * 100);
            progressBar.Position = percentage;
            Application.DoEvents();
            if (totalBytes == bytesCopied || cancel == 1)
            {
                DialogResult = DialogResult.OK;                    
            }
        }            
        return 0;
    }
    #endregion
    private void buttonCancel_Click(object sender, EventArgs e)
    {
        cancel = 1;
    }
}

在我的主窗体的代码中,这里是Button Click事件处理程序:

private void buttonCopy_Click(object sender, EventArgs e){
    using(FileCopier fileCopier = new FileCopier()){
         fileCopier.Copy("My source file", "My destination file");
    }
}

就是这样,完成复制后,上面的方法Copy()应该正常退出。我不明白完成复制后仍然在做什么,并使我的主表格冻结。

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

copyFinished未在任何地方修改,主线程无限期地休眠