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为每个复制线程调用,然后在每个完成 9 次(10 次)后销毁,它将全部关闭,但有时我仍然打开一个,所以我尝试使用此代码

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

但我得到一个跨线程错误。我如何确保副本完成后我没有任何PleaseWait打开的表格。

4

3 回答 3

0

这可能是由于引用了来自多个线程的一个 mInstance 字段。

如果您只想显示一份“请稍候”,您应该在创建表单上创建引用计数器 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 回答