C# 如何从两个线程观察列表以更新数据?
我想测试“WaitOne”,现在如果不显示UI,结论是正确的,当它显示UI列表时,它是错误的。我知道为什么会出现这个问题,但我不知道如何解决它 当thd01使用“Application.DoEvents()”时,thd02可以工作,但我需要线程返回thd01继续工作 谁能告诉我,如何解决这个问题C# 如何从两个线程观察列表以更新数据?,c#,multithreading,C#,Multithreading,我想测试“WaitOne”,现在如果不显示UI,结论是正确的,当它显示UI列表时,它是错误的。我知道为什么会出现这个问题,但我不知道如何解决它 当thd01使用“Application.DoEvents()”时,thd02可以工作,但我需要线程返回thd01继续工作 谁能告诉我,如何解决这个问题 private void btn_Base_Click(object sender, EventArgs e) { Thread thd01 = new Thread(new ThreadSta
private void btn_Base_Click(object sender, EventArgs e)
{
Thread thd01 = new Thread(new ThreadStart(Base_thd1));
Thread thd02 = new Thread(new ThreadStart(Base_thd2));
thd01.Start();
thd02.Start();
}
private void Base_thd1()
{
if (list_Base.InvokeRequired)
{
BeginInvoke(new OnUpdateListInvokeDelegate1(Base_thd1));
}
else
{
list_Base.Items.Add("Start thd1");
Application.DoEvents();
list_Base.Items.Add("thd1 Sleep");
Thread.Sleep(3000);
list_Base.Items.Add("End thd1");
list_Base.Items.Add("Set ");
mre.Set();
}
}
private void Base_thd2()
{
if (list_Base.InvokeRequired)
{
BeginInvoke(new OnUpdateListInvokeDelegate1(Base_thd2));
}
else
{
list_Base.Items.Add("Start thd2");
list_Base.Items.Add("thd2 Wait...");
mre.WaitOne()
list_Base.Items.Add("End thd2");
}
我创建了两个线程来测试WaitHandle.waitone
,
如果我不显示UI,正确的结论如下
启动thd1
thd1睡眠
启动thd2
等待。。。
结束thd1
第1组
结束thd2
当thd1处于睡眠状态时,thd2进程将一直运行,直到WaitOne
。
然后苏醒过来,
它与thd2通信,允许thd2进程继续运行
如果我想显示UI的列表就不同了。需要考虑主线程。
首先我调用主线程,让thd1可以显示UI列表,但它需要断点,所以我认为使用“Application.DoEvents()”让thd2在thd1睡眠时继续运行是可行的 但它无法返回thd1 流程图:thd1->(确定)thd2->(如何做。)thd1
启动一个新线程,该线程检查它是否在GUI线程中运行(通过测试.InvokeRequired()
。如果是这种情况(在第一次调用中总是会出现),则调用BeginInvoke()
它将排队在GUI线程上调用您的方法。然后,当您的方法在GUI线程中第二次被调用时,您将再次测试您是否在正确的线程上,如果是(现在是),您将开始从GUI线程内向列表添加项目
这意味着,您的Thread.Sleep()
和列表填充将在GUI线程中调用。您创建的所有线程所做的就是将调用转发到GUI线程并退出
对于第一个模拟,您应该将方法重写为以下内容:
private void Base_thd1()
{
BeginInvoke(new Action(() => list_Base.Items.Add("Start thd1")));
Thread.Sleep(3000);
BeginInvoke(new Action(() => list_Base.Items.Add("End thd1")));
BeginInvoke(new Action(() => list_Base.Items.Add("Set ")));
BeginInvoke(new Action(() => mre.Set()));
}
也许您应该看看。它在不同的线程中运行代码,您可以在该方法中调用
ReportProgress()
,它将在GUI线程中执行附加到ProgressChanged
的方法。该方法完成后,它还会在GUI线程中调用附加到RunWorkerCompleted
的方法。您能否进一步阐明您想要实现的目标?进一步说明应该实现的顺序,例如thread1 do ope然后,thread2在Thread1等待时执行一些操作,等等。啊,好的应用程序。DoEvents()
黑客…