2012-05-22 29 views
5

Tôi có giải pháp làm việc báo cáo tiến trình & văn bản tới thanh tiến trình và nhãn trên biểu mẫu chính của ứng dụng. Bây giờ tôi đã chuyển các phương thức công nhân của tôi sang một lớp học để họ có thể truy cập được qua nhiều hình thức, v.v.Tiến trình báo cáo của BackgroundWorker từ Lớp ngoài?

Trong các phương thức công nhân là các câu lệnh BW.ReportProgress() đẩy lùi tiến trình và văn bản vào BackgroundWorker trong biểu mẫu chính.

Để cung cấp cho một ý tưởng tốt hơn ở đây là cách bố trí file:

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(); 
} 

Sau đó, lớp tôi mới được tạo ra mà bao gồm tất cả các phương pháp nhân và là để đẩy nhanh tiến độ để hình thức chính.

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); 
     } 
    } 
}

Vấn đề tôi đang gặp là trong lớp XMLandRar các CreateRarBW không được công nhận (rõ ràng) - làm thế nào tôi có thể thực hiện cuộc gọi ReportProgress để BW trong màn hình chính của ứng dụng?

Trả lời

9

Tạo sự kiện trong lớp học XMLandRar mà bạn có thể đăng ký.

Bằng cách này, lớp XMLandRar không cần phải biết hoặc quan tâm đến giao diện người dùng hoặc thanh tiến trình, nó chỉ quan tâm đến việc gửi tin nhắn nếu có ai đó lắng nghe.Và cũng có thể có nhiều hơn một thuê bao (giả sử nếu bạn muốn báo cáo cho người lao động nền và một khúc gỗ, có lẽ)

Ví dụ:

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

Chính xác những gì tôi đã làm sau, +1! –

+0

Tất nhiên điều này có thể được tối ưu hóa một chút và mở rộng, nhưng bạn sẽ có được ý tưởng cơ bản. =) –

5

Đối tượng sender trong cuộc gọi DoWork gọi là trường hợp BackgroundWorker gọi lại cuộc gọi lại này.

Điều này cho phép sử dụng cá thể và thêm nó vào lớp mới XMLandRar của bạn.

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) 
    { 
    // ... 
    } 
} 


Hoặc bạn thiết lập dụ BackgroundWorker như một tài sản cho XMLandRar lớp.

public class XMLandRar 
{ 
    protected BackgroundWorker mWorker; 

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


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

Hoặc như đã đề cập trong các ý kiến, bằng sự kiện trong lớp 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)); 
     } 
    } 
} 

Cách sử dụng:

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); 
} 

Hy vọng rằng không có nguyên nhân lỗi chính tả 'Tôi đang ở văn phòng.

+0

@HenkHolterman - bạn có thể xây dựng trong một hãy trả lời? Bạn có nghĩa là đó là một lớp tái sử dụng thích hợp thì RarFiles không được biết về GUI vì điều đó sẽ làm cho nó cụ thể cho tình huống đó? –

+0

@HenkHolterman Vì vậy, những gì tôi thực sự cần làm là tách biệt mã GUI sửa đổi, đặt nó trong biểu mẫu chính và chỉ có một sự kiện cập nhật báo cáo chung/gọi lại trong lớp mà bất kỳ biểu mẫu/CLI/trang nào có thể nghe và xử lý đó là cách riêng? –

+0

Tôi đã cập nhật câu trả lời của tôi, nếu điều đó giúp .. –

0

Tôi đã cố định lỗi trong mã trình và làm sạch nó lên ... Đây là một mẫu làm việc sẽ giúp những người có thể không hiểu mã vì nó đã bị phá vỡ như nó đã được ... Mặc dù tôi muốn nói rằng ý định và chức năng của mã sau khi nó được làm sạch lên và nâng cao là tuyệt vời.

Đây là mã hoạt động có thể giúp bạn bắt đầu trong dự án của mình để sử dụng chuỗi backGroundWorker cho bất kỳ thứ gì bạn cần.

Chỉ việc điều chỉnh phương pháp này -

public void RarFiles(List<string> repSelected) 

Để làm bất cứ điều gì làm việc bạn cần. Bạn cũng sẽ phải thay đổi các tham số bạn có kế hoạch sử dụng .. tức là bạn có thể cần một DataTable hoặc một số đối tượng tùy chỉnh ... Bạn có thể thay đổi

 public class OnXmlandRarUpdateEventArgs : EventArgs 

Đối với nhu cầu của bạn .. như vậy khi bạn nhận được một gọi lại .. bạn có thể cập nhật hình thức giao diện người dùng chính của bạn với những thay đổi được thực hiện đối với những mặt hàng ..

bạn có thể cần phải thực hiện một số tinh chỉnh .. nhưng bạn thấy những gì tôi có nghĩa là ..

Đây là Bộ luật Mẫu. Đừng quên tạo một nút trên biểu mẫu ...

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); 
      } 
     } 
    } 

Đây là mã lớp. Bạn chỉ có thể tạo ra một lớp trong dự án hiện tại của bạn ... Hãy nhớ rằng đối tượng CreateRarBW là một trường hợp BackgroundWorker ... (Đã được không bao gồm ở trên ..)

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)); 
       } 
      } 
     } 

    } 
Các vấn đề liên quan