5

進行状況とテキストを進行状況バーとアプリケーションのメインフォームのラベルに報告する実用的なソリューションがあります。複数のフォームなどでアクセスできるように、ワーカー メソッドをクラスに移動しました。

ワーカー メソッド内には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);
        }
    }
}

私が抱えている問題は、クラスで CreateRarBW が (明らかに) 認識されないことです。アプリケーションのメイン画面で BW を呼び出すにはXMLandRarどうすればよいですか?ReportProgress

4

3 に答える 3

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 });
            }
        }
    }
}
于 2012-05-22T11:14:00.750 に答える
5

コールバック内のsenderオブジェクトは、このコールバックを呼び出しているインスタンスです。DoWorkBackgroundWorker

これにより、インスタンスを使用して新しい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);
}

私はオフィスにいるので、タイプミスがなければいいのですが。

于 2012-05-22T10:42:18.360 に答える
0

提出されたコードのエラーを修正し、クリーンアップしました...これは、コードがそのまま壊れていたためにコードを理解できなかった可能性がある人を助ける作業サンプルです...クリーンアップされ、強化された後のコードの意図と機能は優れています。

これは、必要に応じて 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));
                }
            }
        }

    }
于 2015-11-07T23:36:57.323 に答える