2016-07-27 3 views
1

Ниже приведен пример кода, для этого используется devexpress bareditItem (progressbar), чтобы показать прогресс при загрузке данных. Я хотел бы знать, есть ли способ показать тот же индикатор выполнения (показать прогресс при загрузке данных) с помощью async wait и task.Фоновый работник для async ждут задачи

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace ProgressBar { 
    public partial class Form1 : DevExpress.XtraEditors.XtraForm { 

     DataTable workTable; 

     public Form1() { 
      InitializeComponent(); 
      workTable = new DataTable("Records"); 
      workTable.Columns.Add("Id", typeof(int)); 
      workTable.Columns.Add("Data", typeof(String)); 
     } 

     //this data varies from 0 to 50,000 rows 
     private void LoadData(DoWorkEventArgs e) { 
      for(int i = 0; i < 1001; i++) { 
       System.Threading.Thread.Sleep(5); 
       workTable.Rows.Add(i, String.Format("Record {0}", i)); 
       this.backgroundWorker1.ReportProgress(i, i); 
      } 

     } 

     private void button1_Click(object sender, EventArgs e) { 
      this.backgroundWorker1.RunWorkerAsync(); 
     } 

     private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { 
      LoadData(e); 
     } 

     private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { 
      DataTable up = workTable.Clone(); 
      this.barEditItem1.EditValue = e.ProgressPercentage; 
     } 

     private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
      gridControl1.DataSource = workTable; 
     } 
    } 
} 

ответ

1

BackgroundWorker является устаревшей функция для меня (С момента выхода функции асинхронной-ждут). Старайтесь не использовать его с этого момента. Это эквивалентно с использованием ожидаемого асинхронного ожидания:

private async void button1_Click(object sender, EventArgs e) 
{ 
    await LoadData(); 
} 

private async Task LoadData() 
{ 
    for (int i = 0; i < 1001; i++) 
    { 
     await Task.Delay(5); 
     workTable.Rows.Add(i, String.Format("Record {0}", i)); 

     DataTable up = workTable.Clone(); // useless but copied from your code 
     this.barEditItem1.EditValue = i; 
    } 
    gridControl1.DataSource = workTable; 
} 
+0

BackgroundWorker не устарел. – LarsTech

+1

@LarsTech Не рекомендуется использовать после выхода async-ожидания. – user3185569

-1

Несомненно, есть. Не используйте фоновый рабочий вообще, поскольку он устарел.

Вот какой-то (непроверенный) код, который должен вас устроить. SynchronizationContext предотвращает перекрестные потоки. Там может быть лучший способ сделать это, но это то, что я использую.

namespace ProgressBar 
{ 
    using System.ComponentModel; 
    using System.Data; 
    using System.Threading; 
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Drawing; 
    using System.Linq; 
    using System.Text; 
    using System.Windows.Forms; 

    public partial class Form1 : DevExpress.XtraEditors.XtraForm 
    { 

     private DataTable workTable; 
     private SynchronizationContext _context; 

     public Form1() 
     { 
      InitializeComponent(); 

      this._context = SynchronizationContext.Current; 

      workTable = new DataTable("Records"); 
      workTable.Columns.Add("Id", typeof(int)); 
      workTable.Columns.Add("Data", typeof(String)); 
     } 

     private async Task LoadData() 
     { 
      const int iterations = 1001; //whatever you want... 

      for (int i = 0; i < iterations; i++) 
      { 
       workTable.Rows.Add(i, String.Format("Record {0}", i)); 
       this._context.Post(() => 
       { 
        this.UpdateWorkProgress((int) i /iterations) 
       }); 
      } 
     } 

     private void UpdateWorkProgress(int percent) 
     { 
      this.barEditItem1.EditValue = percent; 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      await this.LoadData(); 
      gridControl1.DataSource = workTable; 
     }   
    } 
} 
+0

Почему downvote? – Brandon

1

Ваш код может быть преобразован и упрощен с помощью async/await рисунка и Progress<T> класса, чтобы гарантировать, что обновление доклада о ходе работы происходит на правильной резьбе:

namespace ProgressBar { 
    public partial class Form1 : DevExpress.XtraEditors.XtraForm { 

     DataTable workTable; 

     public Form1() { 
      InitializeComponent(); 
      workTable = new DataTable("Records"); 
      workTable.Columns.Add("Id", typeof(int)); 
      workTable.Columns.Add("Data", typeof(String)); 
     } 

     //this data varies from 0 to 50,000 rows 
     private void LoadData(IProgress<int> progress) { 
      for(int i = 0; i < 1001; i++) { 
       System.Threading.Thread.Sleep(5); 
       workTable.Rows.Add(i, String.Format("Record {0}", i)); 
       progress.Report(i); 
      } 
     } 

     private async void button1_Click(object sender, EventArgs e) { 
      // 1. This replaces: backgroundWorker1_ProgressChanged 
      var progress = new Progress<int>(
       i => 
       { 
       // This code will execute on the UI thread, as it should 
       DataTable up = workTable.Clone(); 
       this.barEditItem1.EditValue = i; 
       }); 

      // 2. This replaces: backgroundWorker1_DoWork 
      await Task.Run(() => this.LoadData(progress)); 

      // 3. This replaces: backgroundWorker1_RunWorkerCompleted 
      gridControl1.DataSource = workTable; 
     } 
    } 
} 

я оставил в нескольких строках коды что у вас есть, что я не думаю, что вам действительно нужно, например Thread.Sleep и DataTable up = workTable.Clone();, но я уверен, что вы можете это понять.

+0

Ooooooh, я не знал о 'IProgress '. Милая. – Brandon

Смежные вопросы