2014-11-23 72 views
1

我有一個顯示對話框的線程。我爲此使用線程的原因是因爲我希望對話框立即顯示(所以我使用ShowDialog())),而主線程繼續執行一些繁重的工作。當主線程完成「重」功能時,我希望對話框停止顯示。在線程中關閉一個WPF - C#

這是我使用的代碼:

Thread searchingAlertThread = (new Thread(() => 
{ 
    SearchingAlert searchingAlert = new SearchingAlert(); 
    try { 
     searchingAlert.ShowDialog(); 
    } catch (ThreadAbortException) { // Thrown when the thread is aborted 
     searchingAlert.Close(); 
    }       
})); 
searchingAlertThread.SetApartmentState(ApartmentState.STA); 

searchingAlertThread.Start(); // Starts the thread 
BluetoothDeviceInfo[] devices = client.DiscoverDevices(); // Takes 15 seconds 
searchingAlertThread.Abort(); // Stops the thread 

searchingAlertWPF窗口對話框,顯示TextViewImageView用gif動畫。

問題是,有時當這個被調用的被調用的次數多於一次(如果沒有找到任何設備),ImageView沒有顯示,更重要的是,不會拋出ThreadAbortException。 這是用對話框關閉線程的正確方法嗎?

+0

使用'Invoke()'''關閉()'對話框。 – SLaks 2014-11-23 21:30:06

+0

@SLaks抱歉誤會,但它是WPF ...我編輯了這個問題 – SharonKo 2014-11-23 21:34:11

+0

不使用ShowDialog。如果您需要打開一個線程來創建一個窗口而不是另一個窗口,那意味着有些問題......爲什麼不打開一個窗口或創建一個顯示進度的用戶控件呢? – 2014-11-23 22:10:01

回答

2

原始示例至少存在兩個主要問題:運行新的UI線程並中止線程。試試這個:

SearchingAlert searchingAlert = new SearchingAlert(); 
BluetoothDeviceInfo[] devices = null; 

searchingAlert.Loaded += async (sender, e) => 
{ 
    devices = await Task.Run(() => client.DiscoverDevices()); 
    searchingAlert.Close(); 
}; 

searchingAlert.ShowDialog(); 

// Use the devices array here 

目前還不清楚是什麼client是,當然,如果它提供的DiscoverDevices()方法的異步版本,你應該只是等待上,而不是使用Task.Run()

+0

謝謝SharonKo試圖修復我的答案中的代碼。我很驚訝你的編輯被其他SO評論者拒絕了。這是一個很好的編輯,我已經提前完成了你提出的改變。 – 2014-11-24 18:24:20