2010-03-02 60 views
2

我正在通過僅僅製作一個WPF應用程序單實例的需求。 但是 - 我必須將命令行傳遞給第一個實例,然後執行一些UI操作。來自其他線程的WPF訪問GUI

我正在使用Mutext檢查已運行的實例,我使用NamedPipes將命令行轉移到已經運行的實例。

但當然,我不是在正確的線程訪問「Window1」。 我嘗試在靜態類中存儲對「Window1」的引用,然後使用Dispatcher在「Window1」中調用方法,但是,只要我嘗試訪問變量(「Window1」中的類範圍廣)I會收到「未設置爲對象實例的對象引用」。

UI操作是爲TabControl添加一個新的Tab - 在新Tab的初始化過程中,一些工作已經完成 - 並且變量被初始化,甚至我想調用的方法在init中工作 - 但是當從調度程序失敗。

任何提示,如何做到這一點?我在這裏錯了嗎?

謝謝!

回答

4

這很簡單:

void ProcessCommandLine(string commandLine) 
{ 
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => 
    { 
    ... code to process the command line here ... 
    }); 
} 

您可以從App.Startup從你的線程,從命名管道接收消息稱此也。

這裏的關鍵考慮因素是:

  1. 使用的BeginInvoke,而不是調用的,以防止調用線程從等待
  2. 使用DispatcherPriority.ApplicationIdle的保證應用程序完成初始化命令行處理之前
  3. 使用Application.Current.Dispatcher代替Window1.Dispatcher的情況下,窗口1尚未initialzed
+0

偉大的信息射線。我之前發佈的解決方案是我遇到的問題,以解決我遇到的問題,並簡單地轉發該信息。我做了一些更多的研究,發現你發佈了同樣的東西(BeginInvoke可能會解決OP的問題)。我對使用lambda表達式而不是回調函數的更多信息感興趣。我使用我在幾個地方發佈的代碼,並且正在考慮改變它,如果有更好的方法。你有什麼鏈接進入更深層次的解釋?再次感謝! – Scott 2010-03-02 20:35:01

+1

@Scott:lambda表達式實際上只是語法糖。我在其他評論中提到的性能差異是什麼讓我們忽略了對Dispatcher.CheckAccess的調用。 Dispatcher.Invoke已經做了Dispatcher.CheckAccess()內部,因此調用Dispatcher.Invoke之前做重複工作和雜波的代碼。當你在同一個線程性能相當於但是當你沒有,的checkAccess()被調用三次,如果我們手動調用它(從調用代碼的調用之前一次,一次,一旦在遞歸調用)。 – 2010-03-02 22:46:00

+0

再次感謝您的回覆!這非常有趣!我發現的所有文章(包括msdn)都建議添加Dispatcher.CheckAccess以防止不必要的調用(請參閱鏈接)。我不打算懷疑,但我希望你能指點我一些文件。感謝您分享您的知識! 鏈接: http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.checkaccess(VS.100).aspx http://social.msdn.microsoft.com/論壇/ EN-US/WPF /線程/ 14f7ca5e-fb1c-433E-94d4-269c3ddcedec http://blog.decarufel.net/2009/03/good-practice-to-use-dispatcher-in-wpf.html – Scott 2010-03-02 23:41:02

2

這是不對的,你確定互斥體是正確地將控制權傳遞給你當前正在運行的應用程序實例嗎?

如果這是一個線程UI訪問問題,您應該收到此錯誤:調用線程無法訪問此對象,因爲不同的線程擁有它。

事實上,您得到的「對象引用未設置爲對象的實例」。錯誤消息意味着你還沒有將對象實例化爲新的。

+0

我會同意的這個評估。我也相信這裏還有其他一些問題。我會嘗試調試並找到您嘗試訪問的對象爲null。 – Scott 2010-03-02 15:00:39

+0

看來我進入了某種競爭狀態,正如我一步一步建立起來的那樣,我非常想知道爲什麼這個該死的對象沒有初始化。 我目前的工作解決方案是來自WinForms的糟糕的舊的DoEvents()。幾個測試表明,它現在正在工作,根據需要,但如果任何人比DoEvents()更好的主意()我會很高興,...... 謝謝! – JerryVienna 2010-03-02 15:35:13

+0

+1表示它不是WPF的調度員抱怨 – 2010-03-02 19:40:33