我几乎每天都使用后台工作人员而且效果很好。今天我来到了一个实例,虽然我需要将我的后台工作者放在一个单独的项目中,然后是我正在运行的项目,因为我需要在我的解决方案中将这个类用于两个不同的项目中。当我在winforms表单上测试编码时,它完美地运行,在后台线程上处理我的编码。当我尝试从外部项目引用这个类时,我的所有编码似乎运行得很好,但它似乎没有在后台线程上做任何事情,因为它应该是,导致我的主窗口锁定。
有没有办法解决这个问题/什么是外部类ASYNC调用的最佳做法。
注意我基本上创建了一个调用start的类,并且在数据就绪时会触发事件,因此我的外部项目不会等待方法完成。
提前致谢
我的senerio示例
解决方案ABC有两个项目。项目A和项目B.项目A是我的WPF应用程序,B是我的DLL工作。在项目A里面我有
Dim SmartCardData as new Solution.B()
SmartCardData.Start()
Project B has a sub
Public Sub Start()
worker.workerConnect.RunWorkerAsync()
End Sub
Private Sub workerConnect_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles workerConnect.DoWork
'loop 10 seconds connecting to my device
e.Result = true
End Sub
Private Sub workerConnect_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles workerConnect.RunWorkerCompleted
RaiseEvent Scanner_Connected()
End Sub
(抱歉,我无法将其编码显示为代码,而不是纯文本)
答案 0 :(得分:1)
首先使用调试器。在DoWork事件处理程序上设置断点。当它中断时,使用Debug + Windows + Threads并验证它是否在工作线程上运行,并且您看到列出了主线程。双击主线程并查看调用堆栈,确保它处于空闲状态,并且没有像等待BGW完成那样做。这是一个有保障的僵局。
下一种失败模式很难诊断。当您经常调用ReportProgress时,即使使用后台工作程序,也可以冻结UI线程。 UI线程充满了调用请求,并且不再需要执行正常的任务。喜欢绘画和回应输入。一切仍然像它应该工作,工作者和UI线程实际上正在运行,你只是看不到它。
这很容易发生,每秒报告进度超过一千次是危险区域。这取决于UI线程在ProgressChanged事件处理程序中需要做多少工作。诊断问题的最佳方法是在ReportProgress()调用之后添加System.Threading.Thread.Sleep(45)。这通常会减慢工作人员的速度,使UI线程有机会赶上。
您可以通过以对人眼有用的速度报告进度来解决问题。每秒25次更新除了模糊之外什么都看不到。将bgw结果收集到像List<>这样的集合对象中所以你可以通过一次调用来更新UI,比如AddRange()。如果BGW生成的结果远远超过用户界面消耗的结果,那么这可能仍然不够好,你必须跳过结果或人为地减慢工作人员。
答案 1 :(得分:0)
后台工作者在主线程中处理它完成的代码,阻止UI响应。如果您在后台工作完成时不想更新UI,请不要使用后台工作程序。
答案 2 :(得分:0)
如果您的外部应用程序是基于安慰的,请使用ThreadPool来运行异步工作。 BackgroundWorker委托需要一个消息泵才能在主线程上执行。