的情况
我试着用一个小例子来解释我的问题。我有一个管理视图堆栈的类。替换视图显示并初始化它们等。
class ViewManager()
{
void ReplaceView()
{
RemoveView(...);
InitializeView(...); // this code may call Application.DoEvents()
AddNewView(...);
}
void ShowModalView()
{
ShowView();
Dispatcher.PushFrame()
....
// wait until view can be removed
RemoveView();
}
void RemoveView()
{
...
}
// ... more functions
}
因为ViewManager对UI元素做了很多工作,所以其他线程通过Dispatcher.Invoke.使用ViewManager
Dispatcher.Invoke(new Action(() => m_viewManager.Remove(someView)));
如果现在多个线程在ViewManager上调用操作,并且其中一个线程在代码Application.DoEvents或DispatcherPushFrame中的某个地方调用,则会生成第二个MessageLoop,它将调用视图管理器上的另一个方法。
问题:
- 调用ShowModalView并调用PushFrame
- 在ShowModalView期间,另一个线程调用ShowModalView或ReplaceView
- 因为新的消息循环执行排队到调度器的所有任务,所以也执行该方法
- 因此,ViewManager的两个方法"同时"执行——或者更好,因为它是同一个线程——相互嵌套
ViewManager内部的锁定是无用的,因为它都是同一个线程。信号量可能会冻结UI线程,因为在"ShowModalView"的Message循环期间,另一个线程可以调用调度器上的ShowModalView,这将冻结UI线程。
问题:
- 在"ShowModalView"期间,UI线程应该处理输入/绘制等,但不应该处理通过"Dispatcher.Invoke"调用的其他任务。这可能吗
- 你有其他想法来解决这个问题吗
谢谢你的提示和答案
Manuel
编辑:一种解决方案可能是去掉所有DoEvents和PushFrame代码。这很难实现,但可能是唯一正确的解决方案。这篇文章解释了我的问题的一部分
Application.DoEvents 的使用