我有一个使用BackgroundWorker执行一系列测试的Form。我使用ProgressChanged事件将消息发送到主线程,然后主线程执行UI上的所有更新。我已经梳理了我的代码,以确保我没有对后台工作者的UI做任何事情。我的代码中没有while循环,BackgroundWorker的执行时间有限(以秒或分钟为单位)。但是,出于某种原因,当我锁定计算机时,通常会在我重新登录时挂起应用程序。事实上,当发生这种情况时,BackgroundWorker甚至都没有运行。我认为它与BackgroundWorker有关的原因是因为表单仅在自应用程序加载后执行BackgroundWorker时挂起(它仅在给定某个用户输入时运行)。
我通过RunWorkerAsync方法从我的UI中的TreeView传递了一个TreeNodes列表,但是我只读取了工作线程中的那些节点。我对它们进行的任何修改都是通过progressChanged事件在UI线程中完成的。
我在工作线程中使用Thread.Sleep以定时间隔执行测试(这涉及通过TCP套接字发送消息,而不是在工作线程中创建的)。
我完全不知道为什么我的申请可能会挂起。我确定我在某处做某些“违法”的事情,我只是不知道是什么。
答案 0 :(得分:1)
我通过RunWorkerAsync方法从我的UI中的TreeView传递了一个TreeNode列表,但我只读取了工作线程中的那些节点。
通过“只读”我假设你的意思是“只访问属性getter”。但属性获取者可以执行您无法控制的代码 - 例如,TreeNode.IsSelected将调用本机方法并发送Windows消息(使用Reflector查看)。
相反,您应该从UI线程中的TreeView中提取所需的数据,并将其传递给后台工作程序。你不仅会避免这个问题,而且你的设计也会松散耦合。
答案 1 :(得分:0)
听起来像可怕的UserPreferenceChanged
事件问题,其中在没有消息泵的情况下在后台线程上创建了ui组件。主ui线程同步将事件发送到所有已注册的ui窗口并将挂起,因为后台工作线程上的ui组件无法处理UserPreferenceChanged
事件。
答案 2 :(得分:0)
嗯,这个已经过时了,但事实证明这个问题与我的代码完全无关。由于我们的软件最近发生了变化,日志记录量呈指数级增长,我们的日志缓冲区溢出导致应用程序崩溃。巧合的是,这是在我正在处理这段特定代码的同时发生的。无论如何,我仍然确保我没有对BackgroundWorker中的UI元素进行任何操作,即使它与检查/取消选中TreeNode一样简单。