Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程安全的调用显示窗体和所有者窗体_C#_Multithreading_Forms_Thread Safety - Fatal编程技术网

C# 线程安全的调用显示窗体和所有者窗体

C# 线程安全的调用显示窗体和所有者窗体,c#,multithreading,forms,thread-safety,C#,Multithreading,Forms,Thread Safety,我有一个静态类,它包含所有运行的表单和许多程序变量,如果我需要知道任何程序变量,我会调用这些变量。我想从单独的线程打开新表单,并将其中一个静态表单设置为新表单的所有者。我的代码如下所示: namespace ThreadSafeTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); Pro

我有一个静态类,它包含所有运行的表单和许多程序变量,如果我需要知道任何程序变量,我会调用这些变量。我想从单独的线程打开新表单,并将其中一个静态表单设置为新表单的所有者。我的代码如下所示:

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”的线程以外的线程访问控件“Form1”

我需要调用.ShowForm1_实例,将ProgramState中的静态Form1作为参数。或者在ProgramState中创建一些方法来执行此操作。有可能吗


我读到了:但我不知道如何将这个解决方案应用到我的案例中。如何从单独的线程中获取Form1的线程安全实例以用于Form2的调用显示?

您的表单是在构造函数中创建的,因此主线程拥有它。如果不首先调用回主线程,则无法生成线程并从该线程访问

以下是进一步的细节:


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

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

好的,我知道如何调用控件来更改第一个表单上的标签或颜色中的文本,但我不知道如何将此应用于以表单作为参数调用Show以确保安全。您能将这些详细信息应用到我的代码中,并编写如何使用所有者Form1调用Form2哪个实例处于静态类ProgramState吗?创建一个新线程只是为了调用回主线程没有任何意义。我更新了它,尽管这将在主线程中生成它。除了表单显示之外,您是否还在使用生成的线程进行其他操作?您是否试图让表单在另一个线程上生成?您几乎肯定不想创建多个UI线程。这会让你的生活变得越来越艰难。您希望只有一个UI线程。好的,那么,以所有者表单的消息为中心显示子表单的正确方法是什么。。但是,在静态类中,这个线程所有者表单中的独立线程是否存在?我无法充分支持@Servy的注释。我相信框架本身会抛出异常。正确的方法是使用同一个线程,而不是第二个线程。这就是我评论的全部要点。您只想使用一个UI线程。好的,所以如果我想从单独的线程调用新表单,我可以创建EventHandler,连接到使用Form1中静态类中存储的数据创建Form2的方法,然后从其他线程引发此事件吗?或者这仍然是线程不安全的?创建一个新线程只是为了调用回主线程没有意义。谢谢,但我想从定义为Form1的所有者的线程中显示Form2。。问题在于:在调用时设置所有者。从单独的线程为Form2显示。
if (ProgramState.MainForm.InvokeRequired)
{   
    this.Invoke(() => { ProgramState.MainForm.Show(); });
}
else
{
    ProgramState.MainForm.Show();
}