2012-05-22 4 views
5

진행률 표시 줄에 텍스트 진행 &을보고하고 응용 프로그램의 기본 폼에 레이블을 표시하는 작업 솔루션이 있습니다. 이제는 여러 가지 양식 등을 통해 액세스 할 수있는 클래스로 내 작업자 메서드를 이동했습니다.BackgroundWorker 보고서가 외부 클래스에서 진행됩니까?

작업자 메서드 내에서 진행률과 텍스트를 기본 폼의 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가 인식되지 않는 것입니다 (명백하게) - 어떻게 응용 프로그램의 메인 화면에서 BW에 ReportProgress 전화를 걸 수 있습니까?

답변

9

구독 할 수있는 XMLandRar 클래스의 이벤트를 만듭니다.

이렇게하면 XMLandRar 클래스는 UI 또는 진행률 막대를 알아야하거나 신경 쓸 필요가 없습니다. 누군가가 듣는 경우에만 메시지를 보내는 것에 관심이 있습니다.코드에서

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 클래스에 추가 할 수 있습니다. XMLandRar.cs

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

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


또는 당신이 XMLandRar에 클래스 속성으로 BackgroundWorker 인스턴스를 설정합니다.

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

내가 해결 한 오류를 제출하고 청소 : 또한 하나 이상의 가입자가있을 수

예 (당신은 아마, 배경 노동자와 로그에보고 할 경우의 말을하자) 그것을 위로 ... 이것은 그것이 깨진 이후 코드를 이해하지 못하는 사람들을 도울 수있는 작업 샘플입니다 ... 코드의 의도와 기능을 정리 한 후에도 그 기능을 말하고 싶지만 향상된 기능이 뛰어납니다.

이 코드는 필요한 경우 backGroundWorker 스레드를 사용하기 위해 프로젝트에서 시작할 수있는 작동 코드입니다.

public void RarFiles(List<string> repSelected) 

는 당신이 필요로하는 어떤 작업을 수행하려면 -

그냥이 방법을 수정합니다. 또한 사용하여 당신이 계획 인수를 수정해야합니다 .. 당신이 얻을 때 ... 당신은 당신의 요구에

 public class OnXmlandRarUpdateEventArgs : EventArgs 

을 수정할 수 있습니다 .. 그런 식으로 DataTable을 또는 일부 사용자 지정 개체를해야 할 수도 있습니다 즉,

는 양식 코드입니다 .. 콜백 .. 당신은 .. 해당 항목에 대한 변경과 기본 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)); 
       } 
      } 
     } 

    } 
관련 문제