在我的WPF应用程序中,我的后端运行着许多线程。 我通过以下语法创建它们:
_longRunningThread = new Thread(WorkerOperation);
_longRunningThread.Start();
或
Task.Run(() =>
{
//long running operations
}
然后在WPF应用程序的前端,我有UI线程,该线程需要更新UI元素(可见性,更改颜色,更改为启用/禁用,从数据网格添加/删除项目等)。 。
注册UI的后端引发事件处理程序中的线程/任务。 调用UI侦听器时,我处于调用线程/任务(已在后端调用)的上下文中,因此当我需要更新UI元素(在UI侦听器内)时,我必须上下文切换到UI线程。我通过以下语法做到这一点:
Application.Current.Dispatcher.BeginInvoke(UpdateUiElementsMethod);
据我了解,这会将UpdateUiElementsMethod放在UI线程的队列中,然后(如果我不处理队列的优先级),它 同步 执行添加到队列中的操作。
但是...因为我们只有一个UI线程,并且后端的太多线程/任务引发了事件处理程序,所以UI线程的队列变得满溢,因此可能需要几秒钟的时间在引发后端线程/任务中的事件处理程序与在UI侦听器中的UI Thread中实际执行UI元素的更新之间传递。
Application.Current.Dispatcher.Invoke
也不能解决任何问题:UI队列不会溢出,但是如果UI线程繁忙,则调用实际操作开始执行将花费一些时间(上下文切换到UI线程将花费一些时间) ),同时,它将阻塞调用方线程(在后端创建),直到UI任务完成(直到上下文切换到UI Thread并执行更新UI元素的操作为止),因此使用它可能会对我的后端线程产生负面影响(被阻塞,直到上下文切换到UI线程完成并执行操作为止)。
我是否可以在需要从大量线程/任务中更新UI的WPF应用程序中应用任何替代方法或最佳实践? 我的目标当然是最大程度地减少后端线程引发事件和UI线程中实际UI更新之间的时间。
在开始减少应用程序中的任务/线程或减少后端线程和UI线程之间的上下文切换数量之前,我基本上是在寻找解决方案。