【发布时间】:2014-05-12 07:45:34
【问题描述】:
我有一个静态类,其中包含所有正在运行的表单和许多程序变量,如果我需要知道任何程序变量,我会调用它们。我想从单独的线程打开新表单并将其中一个静态表单设置为新表单的所有者。我的代码看起来像这样(简化):
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”从创建它的线程以外的线程访问。
我需要使用来自ProgramState 的静态Form1 作为参数调用.Show(Form1_Instance)。或者在ProgramState 中创建一些方法来执行此操作。有可能吗?..
我读到这个:C# calling form.show() from another thread 但我不知道如何将此解决方案应用于我的案例。如何获取Form1 的线程安全实例以调用Show for Form2(来自单独的线程)?
【问题讨论】:
-
您几乎肯定不想创建多个 UI 线程。它会让你的生活变得更加艰难。你想拥有一个 UI线程。
-
好的,那么以所有者表单为中心显示“带有消息的子表单”的正确方法是什么..但来自单独的线程(在此线程所有者表单中存在于静态类中)?
-
我对@Servy 的评论赞不绝口。我相信框架本身会在你这样做时抛出异常。
-
你不要。正确的做法是使用同一个线程,而不是第二个线程。这就是我评论的重点。您只想使用 一个 UI 线程。
-
好的,所以如果我想从单独的线程调用新表单,我可以在 Form1 中创建连接到 Method 的 EventHandler(它使用存储在静态类中的数据创建 Form2),然后从其他线程引发此事件吗?或者这仍然是线程不安全的?
标签: c# multithreading forms thread-safety