2017-04-06 18 views
-1

我創建了一個忙框,其中包含一個不確定的進度欄,該進度欄在不同的線程上運行,以便在繁重的任務中主界面無響應時顯示。現在問題是每當我顯示忙碌的窗口時,它就會將開始菜單帶到前面,而應用程序的主窗口全屏運行並在繁忙窗口關閉後恢復正常。顯示在另一個線程上運行的輔助窗口時任務欄的奇怪行爲

Start menu comes to front whenever i show the busy window

Application goes back to full screen once the busy window closes

我可以在我的代碼到處都是這樣做很容易地使用背景工人,但我想要的是一個可重複使用的解決方案。有人能解釋我爲什麼發生這種情況嗎歡迎提出建議。

這裏的BusyBox的

class BusyBox 
    { 
    static BusyBoxWindow BbwP; 
    static Thread WindowThread; 

    public static void ShowBusy() 
    { 
    if (WindowThread == null) 
     { 
      WindowThread = new System.Threading.Thread(() => 
      { 
       SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher)); 
       BbwP = new BusyBoxWindow(); 
       /*BbwP.Owner = HomeWindow.HomeW;*/ // this line throws the exception "The calling thread cannot access this object because a different thread owns it" 
       BbwP.Show(); 

       BbwP.Closed += (s, e) => 
       { 
        Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background); 
       }; 

       System.Windows.Threading.Dispatcher.Run(); 

      }); 
      WindowThread.SetApartmentState(ApartmentState.STA); 
      WindowThread.Start(); 
     } 
     else 
     { 
      BbwP.Dispatcher.Invoke(new Action(() => { BbwP.Show(); })); 
     } 
    } 

    public static void CloseBusy() 
    { 
     BbwP.Dispatcher.Invoke(new Action(() => { BbwP.Hide(); })); 
    } 
} 

回答

0

我想我的類定義的問題是,你需要爲了窗口之間的父/子關係的是要知道,在全屏窗口仍然在最前面。但這意味着兩個UI線程都需要抽取消息才能正常工作。由於你說你阻塞了父級的UI線程,所以無法工作。

解決方案(你似乎已經知道)是不會阻塞UI線程,並讓它繼續做UI的事情,並將繁重的工作轉移到其他線程 - 無論是由後臺工作人員,Task.Run()或無論你認爲合適的其他方式。

+0

事實上,我不能設置繁忙窗口的所有者屬性,因爲我得到「調用線程無法訪問此對象,因爲不同的線程擁有它」異常在運行時。無論如何,我可以設置屬於另一個線程的窗口的所有者屬性?我已經用附加的BusyBox類更新了我的問題,請看看並幫助我。謝謝。 –

+0

如果你的UI線程中的一個保持忙碌狀態,它就不會起作用。一旦你解決了*,你不需要*第二個線程,然後父母/所有者問題不會擔心跨線程問題。 –

+0

所以我可能只需要通過保持線程繁忙來嘗試另一種方式。謝謝你的方式(Y)。 –

0

將「忙碌」窗口的ShowInTaskbar屬性設置爲false後,「任務欄」的怪異行爲消失了。感謝大家爲我的問題揭開一些光芒!