好的,所以我在周末发现了一些奇怪的东西。我有一个WPF应用程序,它产生了一些线程来执行后台工作。这些后台线程然后将工作项目发布到我的同步上下文中。这一切都工作正常,除了一个案件。当我的线程完成时,他们会发布一个动作到调度器上,这个动作将打开一个弹出窗口。最终发生的事情是,如果两个线程都在Dispatcher上发布一个动作,它就开始处理一个动作,然后如果我用Window.ShowDialog()打开一个Popup窗口;当前执行路径暂停等待对话框中的反馈。但问题在于,当对话框打开时,分派器随即启动并立即开始运行已发布的第二个操作。这导致两个代码路径被执行。第一个消息框保持打开状态,而第二个消息框正在运行,因为我的应用程序状态是未知的,因为第一个操作从未完成。WPF调度程序执行多个执行路径
我已经发布了一些示例代码来演示我正在谈论的行为。应该发生的是,如果我发布了2个动作,并且第一个动作打开了一个对话框,那么第二个动作应该在第一个动作完成之后才能运行。
public partial class Window1 : Window {
private SynchronizationContext syncContext;
public Window1() {
InitializeComponent();
syncContext = SynchronizationContext.Current;
}
private void Button_ClickWithout(object sender, RoutedEventArgs e) {
// Post an action on the thread pool with the syncContext
ThreadPool.QueueUserWorkItem(BackgroundCallback, syncContext);
}
private void BackgroundCallback(object data) {
var currentContext = data as SynchronizationContext;
System.Console.WriteLine("{1}: Thread {0} started", Thread.CurrentThread.ManagedThreadId, currentContext);
// Simulate work being done
Thread.Sleep(3000);
currentContext.Post(UICallback, currentContext);
System.Console.WriteLine("{1}: Thread {0} finished", Thread.CurrentThread.ManagedThreadId, currentContext);
}
private void UICallback(object data) {
System.Console.WriteLine("{1}: UI Callback started on thread {0}", Thread.CurrentThread.ManagedThreadId, data);
var popup = new Popup();
var result = popup.ShowDialog();
System.Console.WriteLine("{1}: UI Callback finished on thread {0}", Thread.CurrentThread.ManagedThreadId, data);
}
}
XAML只是一个带有调用Button_ClickWithout OnClick的按钮的窗口。如果你按下按钮两次并等待3秒钟,你会看到你有两个对话框弹出另一个对话框,其中预期的行为将是第一个对话框弹出,然后一旦它关闭,第二个对话框将弹出。
所以我的问题是:这是一个错误?或者我该如何缓解这个问题,以便在第一个动作用Window.ShowDialog()停止执行时,我可以只处理一个动作?
谢谢,劳尔
我确实创建了自己的同步上下文队列,但我一直在寻找更优雅的解决方案。我尝试使用优先级为Normal的调度程序,但得到了相同的结果。我想在一天结束的时候我会改变我的UI,不使用模态对话框。你会认为会有某种方法可以解决这个问题,但我不会。 – HaxElit 2010-05-06 14:25:50