如何结束线程c#交叉线程错误

时间:2012-12-10 14:09:40

标签: c# winforms multithreading

我有一个简单的程序,可以将文件并行复制到多个位置。我有一个弹出作为进度条的表单:

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表单。

3 个答案:

答案 0 :(得分:0)

使用Dispose在正确的主题上调用Control.Invoke

答案 1 :(得分:0)

你应该被称为PleaseWait表格的方法来关闭&自行处理。

并且PleaseWait表格应该使用一个标志是否结束计时器。

答案 2 :(得分:0)

可以引用来自多个线程的一个mInstance字段。

如果您只想显示“请等待”的一个副本,您应该创建参考计数器 mRef ++在创建表单上(当mRef> 0显示/创建表单时),mRef--在关闭表单上(当mRef == 0时,隐藏/关闭表单)。

如果您需要多个“Please Wait”,则应创建一组线程实例。

在这两种情况下,都不应使用线程共享静态字段。