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