具有长处理执行挂起的WPF用户界面
我为这篇冗长的帖子感到非常抱歉。我需要一些关于c#wpf问题的帮助。我已经建立了一个复杂的用户界面(不知何故)和有一些按钮。。。比如开始和停止等 当我单击开始按钮时,执行过程开始于与某些协议层和其他层通信,这是一个漫长的过程。。在这个过程中,我必须显示一些通知界面,如“输入文本”、“选择内容”等。。。这次我要展示一些wpf窗口对象。。。过了一段时间,我不得不自动销毁窗口并再次进行处理 首先,我尝试在主窗口类中运行执行。但结果是当执行开始时。。用户不能点击任何东西,ui也没有响应,只是挂起。我调查这个问题。。。并且发现UI在协议层的执行中忙于处理,所以它没有响应 这是我的问题。。。你能给我一些解决方案吗具有长处理执行挂起的WPF用户界面,wpf,multithreading,process,background,dispatcher,Wpf,Multithreading,Process,Background,Dispatcher,我为这篇冗长的帖子感到非常抱歉。我需要一些关于c#wpf问题的帮助。我已经建立了一个复杂的用户界面(不知何故)和有一些按钮。。。比如开始和停止等 当我单击开始按钮时,执行过程开始于与某些协议层和其他层通信,这是一个漫长的过程。。在这个过程中,我必须显示一些通知界面,如“输入文本”、“选择内容”等。。。这次我要展示一些wpf窗口对象。。。过了一段时间,我不得不自动销毁窗口并再次进行处理 首先,我尝试在主窗口类中运行执行。但结果是当执行开始时。。用户不能点击任何东西,ui也没有响应,只是挂起。我调查
我和后台工作人员,调度员试过了。。。和使用单独的线程。但是没有运气。我想我错过了什么。因为如果我等待显示窗口的结果,窗口肯定会挂起。。如果我用不同的线把它们分开。。它不会相互通信。请给我一些建议
调度员
肯定是解决方案。您可能需要设置。共享一些相关代码也可能会暴露出一些问题。BackgroundWorker应该做您需要的事情。将WorkerSupportsScanCellation和WorkerReportsProgress设置为true
我不建议弹出多个窗口。弹出一个窗口以显示状态。在DoWork中的循环中,调用BackgroundWorker.ReportProgress。然后在ProgressChanged事件处理程序中,更新窗口的状态
要实施停止,请执行以下操作:
在DoWork方法中,需要检查循环中BackgroundWorker的CancellationPending属性。如果为真,则需要退出该方法。在“停止”按钮上单击,调用BackgroundWorker.CancelAsync()。Dispatcher仍然使用主UI线程,并可能导致它在CPU密集型操作期间锁定。@Rachel-这就是为什么我建议使用线程优先级来分配哪个线程应该具有哪个优先级(UI与Worker)@SilverNinja我已经让它锁定了用户界面,即使使用不同的DispatcherPriority。在放弃使用后台线程之前,我以尽可能低的优先级(
SystemIdle
)进行了测试。这是一个CPU密集型操作,而不是像数据库调用一样等待回复。@Rachel-很高兴知道。我通常会将CPU密集型操作卸载到另一个系统(数据库、服务呼叫等),但从未见过您遇到这种锁定。很抱歉,回复太晚。在处理器功能中,我使用AutoResetEvent和计时器。我每200毫秒检查一次协议层的响应。因此,当我通常使用dispatcher/backgroundworker启动进程时,它通常会挂起,因为处理器功能正在等待并使用计时器进行检查。如果UI占用大量CPU,则dispatcher
可能仍会锁定UI,但是backgroundworker
应该可以正常工作。你能给我们看一下你和BackgroundWorker一起试过的代码吗?是的,它能工作。但是当我试图在函数reportProgress中创建wpf窗口的新实例时。。。它总是显示无效操作异常,即。。。“调用线程必须是STA,因为许多UI组件都需要它。”你能提出一些建议,以便我创建一个窗口实例并在中显示它吗。。后台工作程序。当用户单击“取消”按钮时,我将销毁此文件。现在我可以在backgroundworker中运行一个进程,并可以在执行此进程时更新文本框。但主要问题是我无法在backgroundworker中创建另一个wpf窗口的新实例。我在stackoverflow中进行了搜索,发现这是不可能的(!)。back..worker使用MTA线程,在创建新窗口时需要STA线程。这里有一篇详细的文章和一个例子:您不应该在DoWork事件处理程序中修改UI。而是在ProgressChanged或RunWorkerCompleted中更新UI。