繁体   English   中英

调用冻结我的Windows窗体

[英]Invoke freeze my Windows form

我正在尝试做我的第一个多线程Windows窗体应用程序,我有一个重要的问题。 我知道我必须在我的线程中使用Invoke或BeginInvoke来更改我的表单中的RichTextBox,但是当我尝试执行此操作时,我的UI才会冻结,而控制台正在正确打印我的结果。

     class MyThread
    {
        public MyThread()
        {

        }


        public void Run()
        {
            byte[] tmp;
            while (true)
            {

                // lock (sem1)
                Monitor.Enter(sem1);
                {
                    if (end)
                    {
                        Monitor.Exit(sem1);
                        break;
                    }
                        tmp = inp.ReadNr();

                    if (inp.End())
                        end = true;
                }
                if(inOrder)
                Monitor.Enter(sem2);
                Monitor.Exit(sem1);

                bool p = CSL.checkNr((byte[])tmp.Clone());
                Monitor.Enter(sem3);
                if(inOrder)
                Monitor.Exit(sem2);
                {
                    outp.WriteNr(tmp, p);
                    //win.richTextBox2.AppendText(String.Join("", tmp) + '\n');
                    win.richTextBox2.BeginInvoke(new Action(delegate ()
                    {
                        win.richTextBox2.AppendText("wtf");
                    }));
                }
                Monitor.Exit(sem3);

            }
        }
    }

“win”是我的Form1类的对象。 我不能处理它......

编辑:

    static public void loading()
    {
        outp = new oFile();
        Thread[] thr = new Thread[nrThreads];
        for (int a = 0; a < nrThreads; a++)
            new Thread(new ThreadStart(new MyThread().Run)).Start();
        //new MyThread().Run();
        Console.ReadKey();
    }

形成:

private void button1_Click(object sender, EventArgs e)
    {
        Program.loading();
    }

这里的问题是Program.loading这一行:

Console.ReadKey();

这会停止其轨道中的主GUI线程,所以让我们看看现在发生了什么:

  1. 发布到主GUI线程的消息将不会被处理(因为您没有返回到消息循环)
  2. 来自不同线程的BeginInvoke将不会被处理,因为它们通过将消息发布到主GUI线程正在处理的相同消息队列(现在已停止)来工作
  3. 直到你按一个键(假设这是可能的),一切都会停止。 您会注意到表单中的绘制消息将不会被处理,最终表单将淡出并获得“已停止响应”文本。

所以删除那行代码,至少你的程序不应该像往常一样停在它的轨道上。


话虽如此,我建议你先尝试更简单的例子。 您对多个监视器的交错,手动和处理让我觉得您刚刚开始学习多线程编程,并且已经开始使用一些复杂的齿轮,这些齿轮需要非常准确地互锁才能正常工作。

相反,我会要求您查看async / await ,在C#5中添加新关键字来处理异步编程。 虽然异步和多线程不是同一个东西,也不暗示另一个,但异步编程通常会让你走向一个响应的UI,它在等待事物时不会冻结。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM