2012-05-22 40 views
5

我有一個工作解決方案,用於向進度條和應用程序主窗體上的標籤報告進度&文本。我現在已經將我的工作方法移動到一個類中,以便可以通過多種形式訪問它們。BackgroundWorker從外部類報告進度?

在工作方法內有BW.ReportProgress()語句,將進度和文本推送回主表單中的BackgroundWorker。

爲了給出一個更好的主意這裏是文件格式:

MainScreen.cs

List repSelected = new List(); 
XMLandRar xXMLandRar = new XMLandRar(); 

private void Rarbtn_Click(object sender, EventArgs e) 
     { 
      GetReps(); 

      //Run worker 
      if (!CreateRarBW.IsBusy) 
      { 
       CreateRarBW.RunWorkerAsync(); 
      } 
     } 

//Worker 
private void CreateRarBW_DoWork(object sender, DoWorkEventArgs e) 
{ 
    xXMLandRar.RarFiles(repSelected); 
} 

//Progress reporting 
private void CreateRarBW_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    progBar.Value = e.ProgressPercentage; 
    Statuslbl.Text = e.UserState.ToString(); 
} 

然後我的新創建的類,它包含了所有的工人方法,並推動進步的主要形式。

XMLandRar.cs

public class XMLandRar 
{ 
    public void RarFiles(List repSelected) 
    { 
     int step = 100/repSelected.Count(); 
     int i = 0; 
     //Iterate through list and run rar for each 
     foreach (string rep in repSelected) 
     { 
      CreateRarBW.ReportProgress(i, "Raring files for " + rep); 
      DirectoryExists(rep); 
      ProcessRunner(rep); 
      i += step; 
      CreateRarBW.ReportProgress(i, "Raring files for " + rep); 
     } 
    } 
}

我遇到的問題是,在XMLandRar類CreateRarBW無法識別(顯然) - 我怎樣才能使應用程序的主屏幕ReportProgress調用BW?

回答

9

在您可以訂閱的XMLandRar類中創建活動。

這樣XMLandRar類不需要知道或關心用戶界面或進度條,它只關心發送信息,如果有人會聽。而且還可以有一個以上的用戶(讓您是否要在後臺工作和日誌報告,也許說)

例子:提交和清理代碼

private void Rarbtn_Click(object sender, EventArgs e) 
{ 
    GetReps(); 

    //Run worker 
    if (!CreateRarBW.IsBusy) 
    { 
     // This should be done once, maybe in the contructor. Bind to new event. 
     xXMLandRar.ReportProgress += new EventHandler<XMLandRar.ProgressArgs>(xXMLandRar_ReportProgress); 

     CreateRarBW.RunWorkerAsync(); 
    } 
} 

protected void xXMLandRar_ReportProgress(object sender, XMLandRar.ProgressArgs e) 
{ 
    // Call the UI backgroundworker 
    CreateRarBW.ReportProgress(e.Percentage, e.Message); 
} 

public class XMLandRar 
{ 
    // Event handler to bind to for reporting progress 
    public EventHandler<ProgressArgs> ReportProgress; 

    // Eventargs to contain information to send to the subscriber 
    public class ProgressArgs : EventArgs 
    { 
     public int Percentage { get; set; } 
     public string Message { get; set; } 
    } 

    public void RarFiles(List repSelected) 
    { 
     int step = 100/repSelected.Count(); 
     int i = 0; 
     //Iterate through list and run rar for each 
     foreach (string rep in repSelected) 
     { 
      // Report progress if somebody is listening (subscribed) 
      if (ReportProgress != null) 
      { 
       ReportProgress(this, new ProgressArgs { Percentage = i, Message = "Raring files for " + rep }); 
      } 

      DirectoryExists(rep); 
      ProcessRunner(rep); 
      i += step; 

      // Report progress if somebody is listening (subscribed) 
      if (ReportProgress != null) 
      { 
       ReportProgress(this, new ProgressArgs { Percentage = i, Message = "Raring files for " + rep }); 
      } 
     } 
    } 
} 
+0

恰恰是我之後,+1! –

+0

當然,這可以進行一些優化和擴展,但你有基本的想法。 =) –

5

DoWork回調中的sender對象是正在調用此回調的BackgroundWorker實例。

這使得能夠使用該實例並將其添加到新的XMLandRar類。

private void CreateRarBW_DoWork(object sender, DoWorkEventArgs e) 
{ 
    var worker = sender as BackgroundWorker. 
    xXMLandRar.RarFiles(repSelected, worker); 
} 

XMLandRar.cs

public class XMLandRar 
{ 
    public void RarFiles(List repSelected, BackgroundWorker worker) 
    { 
    // ... 
    } 
} 


或者您設置BackgroundWorker實例作爲類屬性的XMLandRar

public class XMLandRar 
{ 
    protected BackgroundWorker mWorker; 

    public XMLandRar(BackgroundWorker worker) { 
     mWorker = BackgroundWorker; 
    } 


    public void RarFiles(List repSelected) 
    { 
     // Do something with {mWorker} 
    } 
} 

或在評論中提到,使用在XMLandRar級賽事

XMLandRar.cs

public class XmlandRarCompletedEventArgs : EventArgs 
{ 
    public readonly bool Finished; 
    public readonly bool Canceled; 

    public XmlandRarCompletedEventArgs(bool finished) 
    { 
     Finished = finished; 
     Canceled = !finished; 
    }  

}public class OnXmlandRarUpdateEventArgs : EventArgs 
{ 
    public readonly int Percentage; 
    public readonly string Message; 

    public XmlandRarCompletedEventArgs(int perc) : 
     this(perc, "") { 
    } 

    public XmlandRarCompletedEventArgs(int perc, string message) 
    { 
     Percentage = perc; 
     Message = message; 
    }  

} 

public delegate void OnXmlandRarDoWorkHandler(object o); 
public delegate void OnXmlandRarUpdateHandler(object o, OnXmlandRarUpdateEventArgs args); 
public delegate void OnXmlandRarCompleteHandler(object o, XmlandRarCompletedEventArgs args); 

public class XMLandRar 
{ 
    public event OnXmlandRarDoWorkHandler OnDoWork; 
    public event OnXmlandRarUpdateHandler OnUpdate; 
    public event OnXmlandRarCompletedHandler OnComplete; 

    public void RarFiles(List repSelected) 
    { 
     TriggerDoWork(); 

     int step = 100/repSelected.Count(); 
     int i = 0; 
     //Iterate through list and run rar for each 
     foreach (string rep in repSelected) 
     { 
      TriggerUpdate(i, "Raring files for " + rep); 
      DirectoryExists(rep); 
      ProcessRunner(rep); 
      i += step; 
      TriggerUpdate(i, "Raring files for " + rep); 
     } 

     TriggerComplete(true); 
    } 


    private void TriggerDoWork() 
    { 
     if (OnDoWork != null) { 
      OnDoWork(this); 
     } 
    } 

    private void TriggerUpdate(perc) { 
    } 
     if (OnUpdate != null) { 
      OnUpdate(this, new OnXmlandRarUpdateEventArgs(perc)); 
     } 

    private void TriggerUpdate(perc, string message) 
    { 
     if (OnUpdate != null) { 
      OnUpdate(this, new OnXmlandRarUpdateEventArgs(perc, message)); 
     } 
    } 

    private void TriggerComplete(bool finished) 
    { 
     if (OnComplete != null) { 
      OnComplete(this, new XmlandRarCompletedEventArgs(finished)); 
     } 
    } 
} 

用法:

private void CreateRarBW_DoWork(object sender, DoWorkEventArgs e) 
{ 
    var worker = sender as BackgroundWorker; 
    // Attach events to class 
    xXMLandRar.OnDoWork += delegate(object o) { 
     // ... 
    }; 
    xXMLandRar.OnUpdate += delegate(object o, OnXmlandRarUpdateEventArgs args) { 
     // ... 
    }; 
    xXMLandRar.OnComplete += delegate(object o, XmlandRarCompletedEventArgs args) { 
     // ... 
    }; 
    xXMLandRar.RarFiles(repSelected, worker); 
} 

希望沒有錯別字,因爲我在辦公室裏來的。

+0

@HenkHolterman - 你能在一個精心製作的請回答?你的意思是說,要成爲一個適當的可重用類,那麼RarFiles一定不知道GUI,因爲它會使它具體到這種情況? –

+0

@HenkHolterman所以我真正需要做的是分離出GUI修改代碼,將其放在主窗體中,並且只有類中的通用報表更新事件/回調,任何窗體/ CLI /頁面都可以監聽和處理這是自己的方式? –

+0

我已經更新了我的答案,如果有幫助.. –

0

我有固定的錯誤它起來......這是一個工作示例,它可以幫助那些可能無法理解代碼的工作示例,因爲它已經被破壞了......儘管我想說清楚它後代碼的意圖和功能up和增強是優秀的。

這是工作代碼,可以讓您開始在項目中使用backGroundWorker線程來滿足您的任何需求。

就修改該法 -

public void RarFiles(List<string> repSelected) 

做任何你需要的工作。你也將不得不修改使用計劃的參數..即你可能需要一個DataTable或一些自定義的對象...... 可以修改

 public class OnXmlandRarUpdateEventArgs : EventArgs 

對於您的需求..這樣當你得到一個回調..你可以更新這些項目所做的更改您的主UI形式..

你可能需要做一些調整。但你明白我的意思..

這就是表單代碼。 。別忘了在窗體上創建一個按鈕...

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 ThreadSample 
    { 
     public partial class Form1 : Form 
     { 
      List<string> repSelected = new List<string>(); 
      XMLandRar xXMLandRar = new XMLandRar(); 
      BackgroundWorker CreateRarBW = new BackgroundWorker(); 
      public Form1() 
      { 
       InitializeComponent(); 
       repSelected = new List<string> { "asdf", "asdfsd", "h;ljj" }; 
       CreateRarBW.DoWork += new DoWorkEventHandler(CreateRarBW_DoWork); 
      } 

      private void Rarbtn_Click(object sender, EventArgs e) 
      { 
       //GetReps(); 

       //Run worker 
       if (!CreateRarBW.IsBusy) 
       { 
        // This should be done once, maybe in the contructor. Bind to new event. 
        xXMLandRar.ReportProgress += new EventHandler<XMLandRar.ProgressArgs>(xXMLandRar_ReportProgress); 

        CreateRarBW.RunWorkerAsync(); 
       } 
      } 

      protected void xXMLandRar_ReportProgress(object sender, XMLandRar.ProgressArgs e) 
      { 
       // Call the UI backgroundworker 
       CreateRarBW.ReportProgress(e.Percentage, e.Message); 
      } 

      //private void CreateRarBW_DoWork(object sender, DoWorkEventArgs e) 
      //{ 
      // var worker = sender as BackgroundWorker; 
      // xXMLandRar.RarFiles(repSelected, worker); 
      //} 


      private void CreateRarBW_DoWork(object sender, DoWorkEventArgs e) 
      { 
       var worker = sender as BackgroundWorker; 
       // Attach events to class 
       xXMLandRar.OnDoWork += delegate(object o) 
       { 
        // ... 
        MessageBox.Show("Hey ... Something is going on over there in the classLib .. " + o); 
       }; 
       xXMLandRar.OnUpdate += delegate(object o, OnXmlandRarUpdateEventArgs args) 
       { 
        // ... 
        //foreach (object oo in args) 
        { 
         MessageBox.Show("Hey ... Something is going on over there in the classLib .. Message is " + args.Message + " and Percentage is " + args.Percentage); 
        } 
       }; 
       xXMLandRar.OnComplete += delegate(object o, XmlandRarCompletedEventArgs args) 
       { 
        MessageBox.Show("Hey ... Something is going on over there in the classLib .. Canceled is " + args.Canceled + " and Finished is " + args.Finished); 
        // ... 
       }; 
       xXMLandRar.RarFiles(repSelected);//, worker); 
      } 
     } 
    } 

這是班級代碼。您可以直接創建在當前項目中的一類...請記住,CreateRarBW對象是一個BackgroundWorker實例......(未包括以上..)

using System; 
    using System.Collections.Generic; 
    using System.Data; 
    using System.Drawing; 
    using System.Linq; 
    using System.Text; 
    using System.IO; 
    using System.Diagnostics; 
    using System.Threading; 

    namespace ThreadSample 
    { 
     public class XmlandRarCompletedEventArgs : EventArgs 
     { 
      public readonly bool Finished; 
      public readonly bool Canceled; 

      public XmlandRarCompletedEventArgs(bool finished) 
      { 
       Finished = finished; 
       Canceled = !finished; 
      } 
     } 

     public class OnXmlandRarUpdateEventArgs : EventArgs 
     { 
      public readonly int Percentage; 
      public readonly string Message; 


      public OnXmlandRarUpdateEventArgs(int perc) : this(perc, "") 
      { 

      } 

      public OnXmlandRarUpdateEventArgs(int perc, string message) 
      { 
       Percentage = perc; 
       Message = message; 
      } 

     } 

     public delegate void OnXmlandRarDoWorkHandler(object o); 
     public delegate void OnXmlandRarUpdateHandler(object o, OnXmlandRarUpdateEventArgs args); 
     public delegate void OnXmlandRarCompleteHandler(object o, XmlandRarCompletedEventArgs args); 

     public class XMLandRar  // : BackgroundWorker 
     { 

      // Event handler to bind to for reporting progress 
      public EventHandler<ProgressArgs> ReportProgress; 

      // Eventargs to contain information to send to the subscriber 
      public class ProgressArgs : EventArgs 
      { 
       public int Percentage { get; set; } 
       public string Message { get; set; } 
      } 

      public event OnXmlandRarDoWorkHandler OnDoWork; 
      public event OnXmlandRarUpdateHandler OnUpdate; 
      public event OnXmlandRarCompleteHandler OnComplete; 

      public void RarFiles(List<string> repSelected) 
      { 
       TriggerDoWork(); 

       int step = 100/repSelected.Count(); 
       int i = 0; 
       //Iterate through list and run rar for each 
       foreach (string rep in repSelected) 
       { 
        TriggerUpdate(i, "Raring files for " + rep); 
        //DirectoryExists(rep); 
        //ProcessRunner(rep); 
        i += step; 
        TriggerUpdate(i, "Raring files for " + rep); 
       } 

       TriggerComplete(true); 
      } 


      private void TriggerDoWork() 
      { 
       if (OnDoWork != null) 
       { 
        OnDoWork(this); 
       } 
      } 

      private void TriggerUpdate(int perc) 
      { 

       if (OnUpdate != null) 
       { 
        OnUpdate(this, new OnXmlandRarUpdateEventArgs(perc)); 
       } 
      } 

      private void TriggerUpdate(int perc, string message) 
      { 
       if (OnUpdate != null) 
       { 
        OnUpdate(this, new OnXmlandRarUpdateEventArgs(perc, message)); 
       } 
      } 

      private void TriggerComplete(bool finished) 
      { 
       if (OnComplete != null) 
       { 
        OnComplete(this, new XmlandRarCompletedEventArgs(finished)); 
       } 
      } 
     } 

    } 
相關問題