C# BackgroundWorker是否从外部类报告进度?
我有一个工作解决方案,它向进度条和应用程序主窗体上的标签报告进度和文本。我现在已经将我的worker方法移动到一个类中,以使它们可以跨多个表单访问 在worker方法中有C# BackgroundWorker是否从外部类报告进度?,c#,.net,winforms,backgroundworker,C#,.net,Winforms,Backgroundworker,我有一个工作解决方案,它向进度条和应用程序主窗体上的标签报告进度和文本。我现在已经将我的worker方法移动到一个类中,以使它们可以跨多个表单访问 在worker方法中有BW.ReportProgress()语句,这些语句将进度和文本以主窗体推送到BackgroundWorker 下面是文件布局,以便更好地了解: MainScreen.cs List repSelected = new List(); XMLandRar xXMLandRar = new XMLandRar(); privat
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();
}
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);
}
}
}
public class XMLandRar
{
public void RarFiles(List repSelected, BackgroundWorker worker)
{
// ...
}
}
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));
}
}
}
然后是我新创建的类,它包含所有的worker方法,并将进程推送到主窗体
XMLandRar.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();
}
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);
}
}
}
public class XMLandRar
{
public void RarFiles(List repSelected, BackgroundWorker worker)
{
// ...
}
}
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));
}
}
}
我遇到的问题是,在
XMLandRar
类中,CreateRarBW没有被识别(显然)-如何在应用程序的主屏幕中对BW进行ReportProgress
调用?DoWork回调中的sender
对象是调用此回调的BackgroundWorker
实例
这样就可以使用实例并将其添加到新的XMLandRar
类中
private void CreateRarBW_DoWork(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker.
xXMLandRar.RarFiles(repSelected, worker);
}
XMLandRar.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();
}
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);
}
}
}
public class XMLandRar
{
public void RarFiles(List repSelected, BackgroundWorker worker)
{
// ...
}
}
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));
}
}
}
或将
BackgroundWorker
实例作为类属性设置为XMLandRar
public class XMLandRar
{
protected BackgroundWorker mWorker;
public XMLandRar(BackgroundWorker worker) {
mWorker = BackgroundWorker;
}
public void RarFiles(List repSelected)
{
// Do something with {mWorker}
}
}
或如注释中所述,使用XMLandRar
类中的事件
private void CreateRarBW_DoWork(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker.
xXMLandRar.RarFiles(repSelected, worker);
}
XMLandRar.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();
}
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);
}
}
}
public class XMLandRar
{
public void RarFiles(List repSelected, BackgroundWorker worker)
{
// ...
}
}
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);
}
希望没有打字错误,因为我在办公室。在您的
XMLandRar
类中创建一个活动,您可以订阅
通过这种方式,XMLandRar
类不需要知道或关心UI或progressbar,它只关心在有人愿意听的情况下发送消息。而且也可以有多个订阅者(比方说,如果您想向后台工作人员报告,可能还需要一个日志)
例如:
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 });
}
}
}
}
private void Rarbtn\u单击(对象发送者,事件参数e)
{
GetReps();
//跑工
如果(!CreateRarBW.IsBusy)
{
//这应该做一次,可能在构造函数中。绑定到新事件。
xXMLandRar.ReportProgress+=新事件处理程序(xXMLandRar\u ReportProgress);
CreateRarBW.RunWorkerAsync();
}
}
受保护的void xXMLandRar_ReportProgress(对象发送方,XMLandRar.ProgressArgs e)
{
//调用UI backgroundworker
CreateRarBW.ReportProgress(例如百分比、消息);
}
公共类XMLandRar
{
//要绑定以报告进度的事件处理程序
公共事务进展;
//Eventargs包含要发送给订阅服务器的信息
公共类ProgressArgs:EventArgs
{
公共整数百分比{get;set;}
公共字符串消息{get;set;}
}
公共文件(已选定列表)
{
int step=100/repSelected.Count();
int i=0;
//遍历列表并为每个列表运行rar
foreach(repSelected中的字符串rep)
{
//如果有人正在收听,则报告进度(已订阅)
if(ReportProgress!=null)
{
ReportProgress(这是新的ProgressArgs{Percentage=i,Message=“Raring files for”+rep});
}
董事会(代表);
ProcessRunner(rep);
i+=阶跃;
//如果有人正在收听,则报告进度(已订阅)
if(ReportProgress!=null)
{
ReportProgress(这是新的ProgressArgs{Percentage=i,Message=“Raring files for”+rep});
}
}
}
}
我已经修复了提交的代码中的错误,并将其清除。。。这是一个工作示例,它将帮助那些可能无法理解代码的人,因为代码已经损坏了。。。尽管我想说,清理和增强后代码的意图和功能非常出色
这是可以让您在项目中开始使用backGroundWorker线程来满足任何需要的工作代码
只需修改此方法-
public void RarFiles(List<string> repSelected)
满足你的需要。。这样当你收到回电时。。您可以使用对这些项所做的更改来更新主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);
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
名称空间线程示例
{
公共部分类Form1:Form
{
List repSelected=新建列表();
XMLandRar xXMLandRar=新的XMLandRar();
BackgroundWorker CreateRarBW=新的BackgroundWorker();
公共表格1()
{
初始化组件();
repSelected=新列表{“asdf”、“asdfsd”、“h;ljj”};
CreateRarBW.DoWork+=新的DoWorkEventHandler(CreateRarBW_DoWork);
}
私有void Rarbtn_单击(对象发送者,事件参数e)
{
//GetReps();
//跑工
如果(!CreateRarBW.IsBusy)
{
//这应该做一次,可能在构造函数中。绑定到新事件。
xXMLandRar.ReportProgress+=新事件处理程序(xXMLandRar\u ReportProgress);
CreateRarBW.RunWorkerAsync();
}
}
受保护的void xXMLandRar_ReportProgress(对象发送方,XMLandRar.ProgressArgs e)
{
//调用UI backgroundworker
CreateRarBW.ReportProgress(例如百分比、消息);
}
//私有void CreateRarBW_DoWork(对象发送方,DoWorkEventArgs e)
//{
//var worker=发送方作为后台工作人员;
//xXMLandRar.rar文件(repSelected,worker);