1
3
当线程第一次命中SetLabelText2时,InvokeRequired将为true,因此
将被调用。 现在,Invoke调用内部实际发生的情况是,您的线程将把委托作为任务传递给UI线程。因此,对SetLabelText2的第二个递归调用将由UI线程完成,而您的线程只是坐着等待UI线程从SetLabelText2返回。因此,您的UI会阻塞,因为UI线程将处于循环中,设置标签文本并休眠,并且没有机会处理消息/事件。 作为一种解决方案,您可以在循环中调用Application.DoEvents(),而不是Sleep(200),但这可能会产生副作用,不建议这样做。 更好的解决方案是将Invoke限制为严格必要的UI调用,在您的示例中:
现在,睡眠将由您的线程完成,并且您的用户界面保持响应。 |
2
0
您的第一个问题是,由于Invoke,SetLabelText2中的Sleep是在UI线程上调用的,而不是在后台线程上调用。这将导致UI显示为锁定状态。新线程仅用于启动SetLabel,但工作几乎立即返回到调用线程。相反,您需要调用循环内部的后台任务,并为每次标签更新委派回UI。 其次,在这个例子中,您不应该创建显式线程。从.Net 4开始,您应该使用Tasks。要模拟使用Thread.Sleep时长时间运行的操作,请使用Task.Delay(200),然后Await或call。显式等待。请记住在后台线程上安排延迟,并委托回UI更新。 |
3
0
好吧,多亏了本节的评论和一些研究的帮助,我终于明白了。 我有点作弊,因为我运行UI线程,只为了在循环或短时间内完成繁重的工作,这里有一些代码-希望这能帮助其他人。
这就是全部:)-希望这能帮助到别人,并感谢所有人帮助我完成我的多线程,是的。。。我知道有更好的方法,但这一种对我有效:) |