好的,所以我在週末發現了一些奇怪的東西。我有一個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