2015-07-22 90 views
0

我的主要形式是執行長操作。爲了告訴用戶應用程序正在處理而不是凍結,我希望以另一種形式實現進度條。實現backgroundworker以另一種形式顯示進度條

如果您不在主線程中,您似乎無法與控件進行交互。 我試圖按照以下鏈接中的建議實施backgroundworker,但沒有成功。

http://perschluter.com/show-progress-dialog-during-long-process-c-sharp/

基於任務的異步模式

How to update the GUI from another thread in C#?

成功的接近我一直在同樣的事情,是在另一個線程封裝的進度條形式的呼叫:

Form_Process f_p = new Form_Process(); 
Thread newWindowThread = new Thread(new ThreadStart(() => 
{ 
    // Create and show the Window 

    f_p.ShowDialog(); 
    // Start the Dispatcher Processing 
    System.Windows.Threading.Dispatcher.Run(); 
})); 

// Set the apartment state 
newWindowThread.SetApartmentState(ApartmentState.STA); 
// Make the thread a background thread 
newWindowThread.IsBackground = true; 
// Start the thread 
newWindowThread.Start(); 

f_p.label_Progression.Text = "Call to exe"; 
f_p.progressBar1.Value = 30; 
f_p.Refresh(); 

但是,當我在主線程中調用函數,並嘗試更新進度欄時,跨線程異常在邏輯上解除。

我錯過了什麼嗎?

回答

1

您無法從其他線程設置窗體上的控件屬性。你需要一個調用來做到這一點。

在您的形式,創建一個函數:不是

f_p.label_Progression.Text = "Call to exe"; 

呼叫

f_p.SetProgressText("Call to exe"); 

同進度條

public void SetProgressText(string value) { 
    if (this.InvokeRequired) { 
     Action<string> progressDelegate = this.SetProgressText; 
     progressDelegate.Invoke(value); 
    } else { 
     label_Progression.Text = value; 
    } 
} 

,然後。你可以把所有的調用放在一個函數中。

+0

非常感謝您的解決方案,看起來不錯!我通過設置全局變量並通過計時器更新表單來繞過問題。 – bill

+0

小心這個定時器解決方案。這個不乾淨。它可能不會只是一個變量的問題,但只要有更多的對象或集合可以被多個線程同時訪問,就會遇到麻煩。 – LInsoDeTeh