0

メインフォームがあります。このフォームにはボタンをクリックすると、プログレスバー付きのコピーウィンドウが表示されます。スレッドを使用してコピー ジョブを実行しますが、コピーが終了すると (ファイルが正常にコピーされ、コピー ウィンドウが閉じられます)、メイン フォームがフリーズします (フォームのコントロールはインタラクティブではないようです)。タスク マネージャーは、あまり作業がない (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;
    }
}

私のメイン フォームのコードでは、ボタン クリック イベント ハンドラーを次に示します。

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

以上で、コピーが終了した後、上記のメソッド Copy() は正常に終了するはずです。コピーが完了した後、まだ何をしているのか理解できず、メイン フォームがフリーズします。

あなたの助けは非常に高く評価されます!

4

1 に答える 1