如何结束线程 C# 跨线程错误



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

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表格仍然打开。

使用 Control.Invoke 在正确的线程上调用Dispose

你应该

被称为PleaseWait表单的方法,以自行关闭和处置。

并且请等待表单应该使用标志来决定是否结束计时器。

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

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

如果需要多个"请稍候",则应创建线程实例数组。

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

最新更新