2011-08-17 63 views
4

我在寫一個數獨求解器應用程序。在某些情況下求解器的計算時間可能會超過3秒,這將需要一個進度條。用於長時間運行功能WP7的進度條C#

所以我的代碼:

private void solveButton_Click(object sender, RoutedEventArgs e) 
{ 
    progressBar1.Visibility = Visibility.Visible; 
    progressBar1.IsIndeterminate = true; 
    mySolver.Solve(initialValue) 
    progressBar1.Visilibity=Visilibity.collapsed; 
    progressBar1.IsIndeterminate = false; 
} 

這裏的代碼是我的實際代碼的精簡版。此代碼不起作用,因爲進度欄完全不顯示。在我看來,UI只有在事件執行完成後纔會更新。如果我在解算器步驟後沒有隱藏進度條,則在解決數獨後出現progressBar。用thread.sleep(1000)代替求解器也會導致相同的UI更新。

感謝您的幫助。

回答

4

問題是, 您需要使用的後臺工作要解決的問題,並在主UI線程你應該顯示進度條的UI線程沒有得到在這兩者之間顯示進度條免費

private void solveButton_Click(object sender, RoutedEventArgs e) 
    { 
     BackgroundWorker bg = new BackgroundWorker(); 
     bg.DoWork += new DoWorkEventHandler(DoWork); 
     bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted); 
     bg.RunWorkerAsync(); 

     progressBar1.Visibility = Visibility.Visible; 
     progressBar1.IsIndeterminate = true;   
    } 

void DoWork(Object sender, DoWorkEventArgs args) 
{ 
    mySolver.Solve(initialValue) 
} 

void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs args) 
{ 

    // this method will be called once background worker has completed it's task 
     progressBar1.Visilibity=Visilibity.collapsed; 
     progressBar1.IsIndeterminate = false 
} 
+0

@Hanan RunWorkerCompleted在UI線程上運行。 – Skomski

+0

對,謝謝 –

1

我不太瞭解WP7,但使用winforms,如果你有一個長時間運行的功能,它需要在與UI不同的線程上運行。

是否可以在WP7上使用BackgroundWorker?您可以更新的ProgressChanged事件的酒吧和改變對RunWorkerCompleted事件

private void solveButton_Click(object sender, RoutedEventArgs e) 
{ 
    progressBar1.Visibility = Visibility.Visible; 
    progressBar1.IsIndeterminate = true; 

    solveButton.Enabled = false; //I reccomend this so the button can't be pressed twice. 

    BackgroundWoker bw = new BackgroundWorker(); 
    bw.RunWorkerCompleted += bw_RunWorkerCompleted; 
    bw.DoWork += bw_DoWork; 
    bw.ProgressChanged += bw_ProgressChanged; 
    bw.RunWorkerAsync() 

} 

private void bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    mySolver.Solve(initialValue, e) 
} 

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if(e.Error != null) 
    { 
     //Handle any exceptions that happened in the background worker. 
    } 
    progressBar1.Visilibity=Visilibity.collapsed; 
    progressBar1.IsIndeterminate = false; 
    solveButton.Enabled = true; 
    ((IDisposable)sender).Dispose(); 
} 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    progressBar1.Value = e.ProgressPercentage; 
} 

//inside mySolver 
void Solve(somthing initialValue, DoWorkEventArgs e) 
{ 
    //Your solver work 
    e.ReportProgress(progress); //a int from 0-100 
    //more solver work 
} 
2

技術上的代碼工作正常的生存能力,你只寫了錯誤的代碼。

解算器在UI線程上運行,因此在再次隱藏它之前,它沒有機會繪製進度條。您需要生成一個線程(或使用後臺工作者)來釋放UI線程,以便繪製您的進度條。

4

您應該在單獨的線程上啓動解算器。這樣,即使在求解過程中,用戶界面線程也可以繼續處理用戶界面對象,這可以讓您的進度條在屏幕上繪製並更新。

0

如果你仍然想在UI線程上運行它(我不推薦!!),你可以使用昨天發佈的WP7 Toolkit的進度條。它包含一個進度條,可以在您的UI線程被阻止時工作。

相關問題