线程安全呼叫显示表单与所有者表单

时间:2014-04-01 13:33:22

标签: c# multithreading forms thread-safety

我有静态类,包含所有正在运行的表单和许多程序变量,如果我需要知道任何程序变量,我会调用它们。我想从单独的线程中打开新表单,并将其中一个静态表单设置为新表单的所有者。我的代码看起来像这样(简化):

namespace ThreadSafeTest
{
    public partial class Form1 : Form
    {
        public Form1()
        { 
            InitializeComponent(); 
            ProgramState.MainForm = this; 
        }

        private void button1_Click(object sender, EventArgs e)
        { 
            Thread t = new Thread(ThreadStartMethod); 
            t.Start(); 
        }

        private void ThreadStartMethod(object obj)
        { 
            new Form2().Show(ProgramState.MainForm); 
        }
    }

    public static class ProgramState
    { 
        public static Form1 MainForm; 
    }
}

呼叫后ThreadStartMethod我得到了这个例外:

  

System.Windows.Forms.dll中发生未处理的“System.InvalidOperationException”类型异常   附加信息:跨线程操作无效:控制从其创建的线程以外的线程访问的“Form1”。

我需要使用.Show(Form1_Instance)中的Form1作为参数调用ProgramState。或者在ProgramState中创建一些方法来执行此操作。有可能吗?..

我读到这个:C# calling form.show() from another thread但我不知道如何将此解决方案应用于我的案例。如何为Form1(来自单独的线程)调用Show获取Form2的线程安全实例?

2 个答案:

答案 0 :(得分:-2)

您的表单是在构造函数中创建的,因此主线程拥有它。您不能首先在不调用主线程的情况下生成线程并从线程访问。

以下是详细信息:

http://msdn.microsoft.com/en-us/library/vstudio/ms171728(v=vs.100).aspx

 namespace ThreadSafeTest
 {
 public partial class Form1 : Form
 {
    public Form1()
    { 
        InitializeComponent(); 
        ProgramState.MainForm = this; 
    }

    private void button1_Click(object sender, EventArgs e)
    { 
        Thread t = new Thread(ThreadStartMethod); 
        t.Start(); 
    }

    private void ThreadStartMethod(object obj)
    { 
        Invoke(() => 
        { 
            ProgramState.MainForm.Show(); 
        });
    }
}

public static class ProgramState
{ 
    public static Form1 MainForm; 
}
}

答案 1 :(得分:-2)

您可以尝试将以下代码放入Form2类的构造函数或您需要显示MainForm实例的任何位置。

if (ProgramState.MainForm.InvokeRequired)
{   
    this.Invoke(() => { ProgramState.MainForm.Show(); });
}
else
{
    ProgramState.MainForm.Show();
}