2016-09-12 3 views
0

У меня проблема с фоновым работником, она дважды называется так, увеличивая время выполнения для моей длительной процедуры, я создал фона рабочего вручную, поэтому нет возможности инициализировать DoWork в методе InitializeComponent() любая помощь приветствуется.BackgroundWorker вызывается дважды?

Вот мой код:

namespace formStudent2 
{ 
    public partial class formStudent2 : Form 
    { 
     private BackgroundWorker backgroundWorker1 = new BackgroundWorker(); 
     private ProgressBar progressBar1 = new ProgressBar(); 
     private Label label1 = new Label(); 

     public formStudent2() 
     { 
      InitializeComponent(); 
     } 
     ... 

     private void btnExportCsv_Click(object sender, EventArgs e) 
     { 
      // Path output file CSV 
      string pathFile = @"D:\DataTest\ListStudent.csv"; 

      int filesCount = 3; 

      // Check if the backgroundWorker is already busy running the asynchronous operation 
      if (!backgroundWorker1.IsBusy) 
      { 
       btnExportCsv.Enabled = false; 
       // This method will start the execution asynchronously in the background 
       backgroundWorker1.RunWorkerAsync(); 
      } 
      else 
      { 
       label1.Text = "Busy processing, please wait..."; 
      } 

      /** 
      * Display dialog Progress Bar : Exporting data... 
      */ 
      Form form = new Form(); 
      form.Text = "Exporting data..."; 
      form.ClientSize = new Size(376, 100); 
      form.FormBorderStyle = FormBorderStyle.FixedSingle; 
      form.ShowIcon = false; 
      form.ControlBox = false; 
      form.MaximizeBox = false; 
      form.MinimizeBox = false; 
      form.StartPosition = FormStartPosition.CenterScreen; 

      label1.AutoSize = true; 
      label1.Location = new System.Drawing.Point(17, 25); 
      label1.Name = "lblPercent"; 
      label1.Size = new System.Drawing.Size(102, 15); 
      label1.TabIndex = 1; 
      label1.Text = "0% Completed"; 
      form.Controls.Add(label1); 

      Button btnCancel = new Button(); 
      btnCancel.Location = new System.Drawing.Point(268, 19); 
      btnCancel.Name = "btnCancel"; 
      btnCancel.Size = new System.Drawing.Size(99, 27); 
      btnCancel.TabIndex = 3; 
      btnCancel.Text = "Cancel"; 
      btnCancel.UseVisualStyleBackColor = true; 
      btnCancel.Click += (senderq, eq) => 
      { 
       if (backgroundWorker1.IsBusy) 
       { 
        // Cancel the asynchronous operation id still in progress 
        backgroundWorker1.CancelAsync(); 
       } 
       else 
       { 
        form.Close(); 
       } 
      }; 
      form.Controls.Add(btnCancel); 


      progressBar1.Location = new System.Drawing.Point(17, 61); 
      progressBar1.Name = "progressBar1"; 
      progressBar1.Size = new System.Drawing.Size(350, 27); 
      form.Controls.Add(progressBar1); 


      backgroundWorker1.WorkerReportsProgress = true; 
      backgroundWorker1.WorkerSupportsCancellation = true; 
      backgroundWorker1.DoWork += (senderq, eq) => 
      { 
       for (int i = 0; i < filesCount; i++) 
       { 
        /** 
        * Export to file CSV 
        */ 
        ExportFileCsv(pathFile, listStudent); 

        int percentage = (i + 1) * 100/filesCount; 
        backgroundWorker1.ReportProgress(percentage); 

        // Set cancellation to pending 
        if (backgroundWorker1.CancellationPending) 
        { 
         // Execute cancellation 
         eq.Cancel = true; 
         backgroundWorker1.ReportProgress(0); 
         return; 
        } 
       } 
      }; 

      backgroundWorker1.ProgressChanged += (senderq, eq) => 
      { 
       // This is updated from doWork. Its where GUI components are update, 
       // receives updates after 100ms 
       progressBar1.Value = eq.ProgressPercentage; 
       label1.Text = eq.ProgressPercentage.ToString() + "% Completed"; 
      }; 

      backgroundWorker1.RunWorkerCompleted += (senderq, eq) => 
      { 
       // Called when the heavy operation in background is over. 
       // Can also accept GUI components 
       if (eq.Cancelled) 
       { 
        label1.Text = "Processing cancelled."; 
       } 
       else if (eq.Error != null) 
       { 
        label1.Text = eq.Error.Message; 
       } 
       else 
       { 
        btnExportCsv.Enabled = true; 
        MessageBox.Show("Export Finished!"); 
        form.Close(); 
       } 
      }; 

      form.ShowDialog(); 
     } 
    } 
} 
+0

Я не знаю, что-то изменит, но вы должны переместить 'backgroundWorker1.RunWorkerAsync();' непосредственно перед 'form.ShowDialog();'. Неправильно запускать BackgroundWorker перед назначением ему задачи. В MSDN есть хороший пример: https://msdn.microsoft.com/fr-fr/library/cc221403(v=vs.95).aspx – gobes

+0

О, ладно. Спасибо. Я буду ссылаться на MSDN – MinhKiyo

+0

определенно, как сказал @gobes, обязательно добавьте события фонарика перед выполнением runworkerasync() – Innat3

ответ

0

текущий статус работника не является статичным. Это зависит от экземпляра нового фонового работника. Попытайтесь сделать его общим.

Ниже какой-то псевдо-кода (я ява парень, никогда не запрограммирован с C# раньше), чтобы сделать это:

public partial class formStudent { 

    boolean workerRunningStatus = false; 

    private void btnExportCsv_Click(object sender, EventArgs e) 
    { 
     // Path output file CSV 
     string pathFile = @"D:\DataTest\ListStudent.csv"; 

     int filesCount = 3; 

     // Check if the backgroundWorker is already busy running the asynchronous operation 
     if (!workerRunning) 
     { 
      btnExportCsv.Enabled = false; 
      // This method will start the execution asynchronously in the background 
      backgroundWorker1.RunWorkerAsync(); 
     } 
     else 
     { 
      workerRunningStatus = true; 
      //then exit 
      return; 
     } 
     //Continue with the remaining logic 
    } 

} 

Это просто все о том, один экземпляр рабочего хода. Или посмотрите, как использовать одноэлементный шаблон в C#.

+0

Спасибо за ответ! – MinhKiyo

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