0

ファイルを複数の場所に並行してコピーする簡単なプログラムがあります。プログレスバーとしてポップアップするフォームがあります。

public partial class PleaseWait : Form
{
    private static PleaseWait mInstance;
    public static void Create()
    {
        var t = new System.Threading.Thread(() =>
        {
            mInstance = new PleaseWait();
            mInstance.FormClosed += (s, e) => mInstance = null;
            Application.Run(mInstance);
        });
        t.SetApartmentState(System.Threading.ApartmentState.STA);
        t.IsBackground = true;
        t.Start();
    }

    public static void Destroy()
    {
        if (mInstance != null) mInstance.Invoke(new Action(() => mInstance.Close()));
    }

    public PleaseWait()
    {
        InitializeComponent();
    }

    public int t = 0;
    private void timer1_Tick(object sender, EventArgs e)
    {
        if (t == 100)
        {
            t = 0;
        }
        else
        {
            t = t + 10;
            progressBar1.Value = t;
        }
    }
}    

コピースレッドごとにを呼び出し、Createそれぞれが10回のうち9回完了すると破棄しますが、すべてを閉じますが、開いたままになることがあるので、このコードを使用してみました

private void closewait()
{
    foreach (Form f in Application.OpenForms)
    {
        if (f is file_copy.PleaseWait)
        {
            f.Dispose();
        }
    }
}

しかし、クロススレッドエラーが発生します。コピーが完了したら、PleaseWaitフォームがまだ開いていないことを確認するにはどうすればよいですか。

4

3 に答える 3

0

複数のスレッドから 1 つの mInstance フィールドを参照している可能性があります。

「お待ちください」のコピーを 1 つだけ表示したい場合は、フォームの作成時に参照カウンター mRef++ を作成し (mRef > 0 がフォームを表示/作成する場合)、フォームを閉じるときに mRef-- を作成する必要があります (mRef == 0 の場合、非表示/フォームを閉じます)。

複数の「お待ちください」が必要な場合は、スレッド インスタンスの配列を作成する必要があります。

どちらの場合も、スレッド共有静的フィールドを使用しないでください。

于 2012-12-10T14:21:57.140 に答える
0

Disposeを使用して、正しいスレッドで呼び出しますControl.Invoke

于 2012-12-10T14:17:01.763 に答える
0

PleaseWait フォームのメソッドを呼び出して、それ自体を閉じて破棄する必要があります。

また、PleaseWait フォームでは、タイマーを終了するかどうかを判断するフラグを使用する必要があります。

于 2012-12-10T14:18:05.410 に答える