Winforms 当UI线程处于睡眠状态时,是否可以无限期地从后台线程块调用方法?
当我在UI线程上调用Thread.Sleep时,后台线程中的所有调用方法是否会自动在UI线程的消息泵中排队,并在最终唤醒时进行处理Winforms 当UI线程处于睡眠状态时,是否可以无限期地从后台线程块调用方法?,winforms,multithreading,deadlock,Winforms,Multithreading,Deadlock,当我在UI线程上调用Thread.Sleep时,后台线程中的所有调用方法是否会自动在UI线程的消息泵中排队,并在最终唤醒时进行处理 我在使用大量线程池线程的winform应用程序中遇到问题,有时该应用程序在锁定/解锁窗口后挂起。一种猜测是UI线程上发生了死锁。另一个是一些UI控件是在后台线程上创建的。(这怎么会导致任何问题?)规则是,只有创建UI控件的线程才应该处理它。这就是为什么会有一个“UI线程”的部分原因——它让你不必猜测你是否需要调用东西或者只是去做。(如果事件发生在UI控件中,则它位于
我在使用大量线程池线程的winform应用程序中遇到问题,有时该应用程序在锁定/解锁窗口后挂起。一种猜测是UI线程上发生了死锁。另一个是一些UI控件是在后台线程上创建的。(这怎么会导致任何问题?)规则是,只有创建UI控件的线程才应该处理它。这就是为什么会有一个“UI线程”的部分原因——它让你不必猜测你是否需要调用
东西或者只是去做。(如果事件发生在UI控件中,则它位于UI线程中,因此您可以直接执行。否则,调用
)因此您希望在该线程中创建控件,并让它按照预期处理所有UI
您的UI线程有一个目的:处理UI中的所有事件,以保持应用程序的响应性,并防止其看起来“冻结”。有时候,它会很忙(处理其他事件),但它应该总是处理一个事件或等待另一个事件。永远不要在UI线程上调用Thread.Sleep
,除非你有一个非常好的理由,并且可以明确地说为什么这不是一个可怕的想法。几乎所有你想用线程来做的事情。睡眠可以用定时器来代替,而且不那么摇晃
简短版本:是的,如果UI线程正在执行某些操作(甚至处于睡眠状态),则对Control.Invoke的调用几乎肯定会一直等待,直到它不执行为止。如果线程处于休眠状态,则可能需要很长时间。是的,在解锁工作站时出现死锁是一个非常臭名昭著的Windows窗体线程问题。我从未对此做出过很好的诊断,但我相当肯定这是由SystemEvents类引起的。这是一个程序初始化问题,当控件开始订阅其事件时,该类会按需初始化
我认为失败模式是在程序主线程以外的线程上创建第一个窗体。比如说,当您创建自己的启动屏幕而不是使用.NET启动屏幕时,您会得到这个结果。或者旋转一个线程来创建它自己的表单实例,并过早地启动它。因此,SystemEvents将从错误的线程触发其事件。SystemSwitch事件在某种程度上是致命的
因此,请仔细查看您的启动代码。在做任何重要的事情之前订阅Main()方法中的一个系统事件应该是一个Q&D修复