我正在尝试做我的第一个多线程窗口表单应用程序,我有一个重要的问题。 我知道我必须在我的线程中使用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();
}
答案 0 :(得分:3)
这里的问题是Program.loading
中的这一行:
Console.ReadKey();
这会停止其轨道中的主GUI线程,所以让我们看看现在发生了什么:
所以删除那行代码,至少你的程序不应该像以前一样停在它的轨道上。
话虽如此,我建议你先尝试一些简单的例子。您对多个监视器的交错,手动和处理让我觉得您刚开始学习多线程编程,并且已经开始使用一些需要非常准确地互锁才能正常工作的复杂齿轮。
相反,我会要求您查看async / await
,在C#5中添加的新关键字来处理异步编程。虽然异步和多线程不是同一个东西,也不暗示另一个,但是异步编程通常会让你走向一个在等待事物时不会冻结的响应式用户界面。