主表单在使用CopyFileEx完成复制文件(带有进度指示器)后被冻结

本文关键字:指示器 冻结 文件 表单 CopyFileEx 复制 | 更新日期: 2023-09-27 18:12:44

我有一个主表单,这个表单有一个按钮,点击它将显示带有进度条的复制窗口。我使用一个线程来完成复制工作,但是在完成复制后(文件被复制并关闭复制窗口),主表单被冻结(窗体上的控件似乎不与之交互)。任务管理器显示没有多少工作(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()方法应该正常退出。我不明白复印完后还在做什么,使我的主表单冻结了。

非常感谢您的帮助!

主表单在使用CopyFileEx完成复制文件(带有进度指示器)后被冻结

copyFinished未被修改,主线程无限期休眠