2013-11-15 59 views
2

我知道這個問題以前曾被問過100次,但是我讀的所有答案都不適合我。所以,我會試試我的運氣,並再次問。ProgressBar從另一個線程更新

我有一個SliderBar調用ValueChanged事件的方法。 在這個方法中,我做了一些需要時間的東西,我希望在這段時間內用戶會看到一個「工作」ProgressBarIsIndeterminate=true)。

不幸的是,我沒有成功讓ProgressBar開始工作(在UI中),直到所有的方法循環完成。 我試過線程,BackgroundWorkerasync任務,但沒有成功..

我做錯了什麼?

這是方法:

private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e){ 
     WorkingBar.IsIndeterminate = true;  //change the progressBar   
     SqlAThread = new Thread(SqlAStart);  
     SqlAThread.Start(); 
    } 

螺紋:

private void SqlAStart() 
    { 
     ... //do some stuff 
    } 
+0

您的doWork方法中的調度程序語法就是您想要使用的,您希望將UI代碼放在那裏以便將您想要執行的操作推送到UI線程上,此刻您似乎在此處所做的只是更改進度欄的屬性,還可以使用此語法更新進度欄。 – JMK

+0

@JMK這個proparty是我想改變的,當這個特性是「真實的」時,progressBar就會處於「工作」模式(我認爲......)。 實際上,它的工作原理,但只有當所有的循環完成.. =/ – Yaron

回答

3

Slider_ValueChanged你開始一個新的胎面運行耗時SqlAStart()方法,但是立即SqlAStart推動工作到UI線程(通過Dispatcher.Invoke())。因此,您的用戶界面會掛起,並且在工作完成之前您沒有看到任何進度。

SqlAStart,只能做你需要更新進度條Dispatcher.Invoke():使用IProgress<T>

private void SqlAStart() 
{ 
    ServerThread = new Thread(HttpSrv.listen); 
    ServerThread.Start(); 
    ... 

    this.Dispatcher.Invoke((Action)(() => { 
     WorkingBar.Value = ...     
    })); 

    .... 
} 
+0

這也應該工作。 – Marc

+0

@Sphinxxx謝謝! – Yaron

0

而不是鍵入出整個漫長的過程,我想請你看看我的答案Progress Bar update from Background worker stalling問題在StackOverflow上。它演示瞭如何正確使用BackgroundWorker對象來更新ProgressBar的進度值。

您可能還想查看MSDN上的BackgroundWorker Class頁面以獲取更多詳細信息。

+0

嗨@sheridan我試過你的代碼(實際上這是我的第一次嘗試) 我明白你的例子,但不sucseed使用它在我的代碼.. – Yaron

+0

@Yaron,現在忽略你的代碼。將該示例代碼放入一個新的WPF應用程序或項目中並使其工作。 *然後*通過一個可行的示例進行試驗,您*應該*能夠將其應用於您的代碼。 – Sheridan

+0

我試過了,它在新項目中工作。但現在當我嘗試在我的代碼中做它dosnt爲我工作 – Yaron

1

這是很容易的:

private async void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 
{ 
    if (State.Value > 0) 
    { 
    var progress = new Progress<int?>(value => 
    { 
     WorkingBar.IsIndeterminate = (value == null); 
     if (value != null) 
     WorkingBar.Value = value.Value; 
    }); 
    await Task.Run(() => doWork(progress)); 
    Task.Run(SqlAStart); 
    } 
    ... 
} 

private void SqlAStart(IProgress<int?> progress) 
{ 
    ServerTask = Task.Run(HttpSrv.listen); 
    ... 
} 

private void doWork(IProgress<int?> progress) 
{ 
    if (progress != null) 
    progress.Report(null); 
    ... 
} 

請注意,您應該(幾乎)從不使用DispatcherThreadBackgroundWorker

+0

嗨@Stephen Cleary,我試過你的代碼(順便說一句,謝謝,我dosnt知道IProgress 之前),但仍然,SqlAstart完成後的UI更新.. – Yaron

+0

@Yaron什麼是方法在做什麼?如果它正在調用UI線程並阻塞它一段時間,那麼顯然沒有其他東西可以在它正在進行時更新。 – Servy

相關問題