BackgroundWorker从外部类报告进度?

Myl*_*ray 5 .net c# backgroundworker winforms

我有一个可用的解决方案,可以将进度和文本报告给应用程序主窗体上的进度条和标签.我现在已经将我的工作方法移动到一个类,以便可以跨多个表单等访问它们.

在worker方法中是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();
}
Run Code Online (Sandbox Code Playgroud)

然后我新创建的Class包含所有的worker方法,并将进度推送到主窗体.

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,在XMLandRar类中,CreateRarBW无法识别(显然) - 如何ReportProgress在应用程序的主屏幕中调用BW?

Mar*_*num 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 });
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


God*_*esZ 5

回调中的sender对象是调用此回调DoWorkBackgroundWorker实例.

这样可以使用实例并将其添加到新XMLandRar类中.

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

XMLandRar.cs

public class XMLandRar
{
    public void RarFiles(List repSelected, BackgroundWorker worker)
    {
    // ...
    }
}
Run Code Online (Sandbox Code Playgroud)


或者BackgroundWorker实例设置为类的属性XMLandRar.

public class XMLandRar
{
    protected BackgroundWorker mWorker;

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


    public void RarFiles(List repSelected)
    {
        // Do something with {mWorker}
    }
}
Run Code Online (Sandbox Code Playgroud)

或者如评论中所述,使用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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

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);
}
Run Code Online (Sandbox Code Playgroud)

希望没有错别字因为我在办公室.