【问题标题】:can't start winForm from a thread无法从线程启动 winForm
【发布时间】:2010-12-03 10:56:18
【问题描述】:

我正在尝试从线程启动一个 winForm,但是当我这样做时,表单显示但没有加载任何标签(它们应该是白色的背景)并且表单被冻结。

我已经用其他一些我知道可以正常工作的 winForms 进行了尝试,但它似乎仍然无法正常工作?有人遇到过这个问题吗?

我知道这个问题含糊不清,但实际上没有任何具体的代码可以帮助理解这个问题。

【问题讨论】:

  • IIRC 在多个线程上创建表单可以工作,但它会使代码特别变得复杂并且容易出现微妙的跨线程问题。我强烈建议在这里坚持一个 UI 线程。无论如何,显示该问题的某种示例代码在这里会有很大帮助。
  • 您确定您的表单有一个当前正在运行的消息循环吗?

标签: c# winforms multithreading


【解决方案1】:

这是因为Message Loop 仅在 UI 线程上运行。并且当在任何其他线程中创建控件或窗口时,它无法访问该消息循环。因此,无法处理用户输入。

要解决这个问题,请尝试从 UI 线程创建一个窗口,并从该窗口创建一个线程,以在不同的线程中执行您想做的任何事情。

【讨论】:

    【解决方案2】:

    UI 线程应该是一个。
    然后,我建议您打开您的表单调用原始表单线程的方法,如下例所示:

    (要对其进行测试,只需创建一个名为 MainForm 的空表单并将此代码粘贴到其中)

    public delegate void OpenFormDelegate(string txt);
    
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            var button1 = new Button();
            button1.Text = "Run for 5 secs and open new window";
            button1.Dock = DockStyle.Top;
            this.Controls.Add(button1);
            button1.Click += new EventHandler(button1_Click);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(Run));
            t.Start();
        }
        public void Run()
        {
            Thread.Sleep(5000); // sleep for 5 seconds
            this.BeginInvoke(new OpenFormDelegate(OpenNewForm), "Hello World !");
        }
        public void OpenNewForm(string text)
        {
            Form f = new Form();
            f.Text = text;
            f.Show();
        }
    }
    

    【讨论】:

      【解决方案3】:

      与线程访问有关,新表单创建后将无法访问UI线程。使用主线程创建表单,使用新线程处理信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-29
        • 2014-06-05
        • 1970-01-01
        • 1970-01-01
        • 2021-01-13
        • 2016-01-23
        相关资源
        最近更新 更多