线程安全调用显示窗体与所有者窗体



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

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 中发生了类型为"System.InvalidOperationException"的未处理异常.dll
其他信息:跨线程操作无效:从创建它的线程以外的线程访问的控件"Form1"。

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

读到这个:C#从另一个线程调用form.show(),但我不知道如何将这个解决方案应用于我的情况。如何获取Form2调用ShowForm1线程安全实例(来自单独的线程)?

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

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

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

以下是更多详细信息:

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; 
}
}

最新更新