我有静态类,包含所有正在运行的表单和许多程序变量,如果我需要知道任何程序变量,我会调用它们。我想从单独的线程中打开新表单,并将其中一个静态表单设置为新表单的所有者。我的代码看起来像这样(简化):
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
的线程安全实例?
答案 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();
}