2013-12-17 71 views
0

請參閱:http://codepaste.net/djw3cw的代碼異步/等待着一個WinForms進度 - 的WinForms版本

如果這是真的,異步/等待異步編程很快就會像LINQ的,我認爲這個問題是一個不平凡的延伸Async/Await with a WinForms ProgressBar

我會很樂意爲指針或代替代碼的文字回答,儘管代碼是最優的。

問題是:如何設置進度條使用異步/等待工作。在過去,我已經成功地使用了一個Dispatcher。

Please see: http://codepaste.net/djw3cw for the code 
What is done: a textbox has any text in it converted to an int, then when 
"mybutton1" is clicked, work is done based on the int, for int ms (int = 
milliseconds). 
During this time, a progressbar "myProgressBar" is shown for 
every tenth-percent step 
When work is complete, the label/textblock controls are updated 
But the below does not work right: the form simply freezes until the work is 
complete. How to fix it? 
How to do this using Task-based Asynchronous Pattern (TAP) or Async/Await, 
rather than a Dispatcher? 

以下是有問題的代碼片斷,不言自明。

private void mybutton1_Click(object sender, RoutedEventArgs e) 
    { 
     myLabel.Content = myTextBox.Text; 

     string myString = myTextBox.Text; 

     bool result = Int32.TryParse(myString, out myInteger); 

     if (result == true) 
     { 
     myTextblock.Text = "Success, thread will be delayed by: " + myInteger.ToString() + " ms"; 

      // 
      int CounterInteger = 0; 
      for (int j = 0; j < myInteger; j++) // set # itt 
      { 

       Thread.Sleep(1); //do some work here 

       // myClassDoWork1.Delay_DoWork(myInteger); //optional way to do work in another class... 

       if (j % (myInteger/10) == 0) //display progress bar in 10% increments 
       { 

        CounterInteger = CounterInteger + 10; 
        myProgressBar.Value = (double)CounterInteger; // won't work here in a parallel manner...must use Dispatcher.BeginInvoke Action 
        //how to make this work using Async/Await? see: https://stackoverflow.com/questions/17972268/async-await-with-a-winforms-progressbar 

       } 

      } 
      /// 
      /// // above does not work properly: the form simply freezes until the work is complete. How to fix it? 
      /// 


      myLabel.Content = "done, delayed work done successfully: in " + myInteger.ToString() + " milliseconds"; 
      myTextblock.Text = "done, delayed work done successfully: in " + myInteger.ToString() + " milliseconds"; 
      return; 
     } 
     else 
     { 
      myTextblock.Text = "Error, integer not entered, try again." + myTextBox.Text; 
      myLabel.Content = "Error, integer not entered, try again."; 
      return; 
     } 


    } 
+0

請編輯代碼到您的問題 - 理想編輯儘可能短,同時仍然是完整的,並展示問題。 –

+0

嗨,喬恩 - 我實際上正在閱讀你關於「C#深度」這個主題的書。你看CodePaste上的代碼行嗎?我發現在這裏切割和粘貼代碼對我來說並不是很好,對不起。 – PaulDecember

+1

是的,我可以在CodePaste上看到代碼 - 但這不是一個提問的好方法。值得熟悉堆棧溢出降價編輯器(和預覽窗口) - 清晰地格式化您的問題(而不僅僅是鏈接到異地代碼)對於創建一個好問題非常重要。 –

回答

5

你不必在你的代碼中的任何asyncawait。你的UI線程阻塞的原因是因爲你正在運行同步代碼。

如果您有要綁定到後臺線程的CPU綁定代碼,請使用Task.Run。然後你可以從UI線程獲得代碼await

private async void mybutton1_Click(object sender, RoutedEventArgs e) 
{ 
    myLabel.Content = myTextBox.Text; 
    string myString = myTextBox.Text; 
    bool result = Int32.TryParse(myString, out myInteger); 

    if (result == true) 
    { 
    myTextblock.Text = "Success, thread will be delayed by: " + myInteger.ToString() + " ms"; 
    IProgress<int> progress = new Progress<int>(value => { myProgressBar.Value = value; }); 
    await Task.Run(() => 
    { 
     int CounterInteger = 0; 
     for (int j = 0; j < myInteger; j++) 
     { 
     Thread.Sleep(1); 
     if (j % (myInteger/10) == 0) 
     { 
      CounterInteger = CounterInteger + 10; 
      progress.Report(CounterInteger); 
     } 
     } 
    } 

    myLabel.Content = "done, delayed work done successfully: in " + myInteger.ToString() + " milliseconds"; 
    myTextblock.Text = "done, delayed work done successfully: in " + myInteger.ToString() + " milliseconds"; 
    return; 
    } 
    else 
    { 
    myTextblock.Text = "Error, integer not entered, try again." + myTextBox.Text; 
    myLabel.Content = "Error, integer not entered, try again."; 
    return; 
    } 
} 
+0

我很欣賞答案。不幸的是,我只是意識到我沒有使用.NET Framework 4.0,所以這些功能在IntelliSense中不顯示。 – PaulDecember

+0

在這種情況下,您可以安裝'Microsoft.Bcl.Async'並使用'TaskEx.Run'而不是'Task.Run'。 –