向后台工作者发送参数? ?

假设我想向后台工作者发送一个 int 参数,这是如何实现的呢?

private void worker_DoWork(object sender, DoWorkEventArgs e) {


}

我知道什么时候该工作。RunWorkerAsync () ; ,我不明白如何在 worker _ DoWork 中定义它应该接受一个 int 参数。

182873 次浏览

您需要 RunWorkerAsync (对象)方法和 参数属性。

worker.RunWorkerAsync(5);


private void worker_DoWork(object sender, DoWorkEventArgs e) {
int argument = (int)e.Argument; //5
}

可以使用 DoWorkEventArgs.Argument属性。

一个完整的例子(甚至使用 int 参数)可以在微软的网站上找到:

你这样开始:

int value = 123;
bgw1.RunWorkerAsync(argument: value);  // the int will be boxed

然后

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
int value = (int) e.Argument;   // the 'argument' parameter resurfaces here


...


// and to transport a result back to the main thread
double result = 0.1 * value;
e.Result = result;
}




// the Completed handler should follow this pattern
// for Error and (optionally) Cancellation handling
private void worker_Completed(object sender, RunWorkerCompletedEventArgs e)
{
// check error, check cancel, then use result
if (e.Error != null)
{
// handle the error
}
else if (e.Cancelled)
{
// handle cancellation
}
else
{
double result = (double) e.Result;
// use it on the UI thread
}
// general cleanup code, runs when there was an error or not.
}

看看 参数属性:

...
backgroundWorker1.RunWorkerAsync(yourInt);
...


private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Do not access the form's BackgroundWorker reference directly.
// Instead, use the reference provided by the sender parameter.
BackgroundWorker bw = sender as BackgroundWorker;


// Extract the argument.
int arg = (int)e.Argument;


// Start the time-consuming operation.
e.Result = TimeConsumingOperation(bw, arg);


// If the operation was canceled by the user,
// set the DoWorkEventArgs.Cancel property to true.
if (bw.CancellationPending)
{
e.Cancel = true;
}
}

尽管这个问题已经得到了回答,我还是会留下另一个 IMO 更容易理解的选项:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (obj, e) => WorkerDoWork(value, text);
worker.RunWorkerAsync();

关于 Handler 方法:

private void WorkerDoWork(int value, string text) {
...
}

可以像这样传递多个参数。

List<object> arguments = new List<object>();
arguments.Add("first");      //argument 1
arguments.Add(new Object()); //argument 2
// ...
arguments.Add(10);           //argument n


backgroundWorker.RunWorkerAsync(arguments);


private void worker_DoWork(object sender, DoWorkEventArgs e)
{
List<object> genericlist = e.Argument as List<object>;
//extract your multiple arguments from
//this list and cast them and use them.
}

如果你想传递不止一种类型的参数,你可以尝试这样做,首先将它们全部添加到 Object 类型的数组中,然后将这个对象传递给 RunWorkerAsync () ,这里有一个例子:

   some_Method(){
List<string> excludeList = new List<string>(); // list of strings
string newPath ="some path";  // normal string
Object[] args = {newPath,excludeList };
backgroundAnalyzer.RunWorkerAsync(args);
}

现在在后台 worker 的 doWork 方法中

backgroundAnalyzer_DoWork(object sender, DoWorkEventArgs e)
{
backgroundAnalyzer.ReportProgress(50);
Object[] arg = e.Argument as Object[];
string path= (string)arg[0];
List<string> lst = (List<string>) arg[1];
.......
// do something......
//.....
}

您应该始终尝试使用具有具体类型的复合对象(使用复合设计模式) ,而不是使用对象类型列表。谁会记得这些东西到底是什么?稍后再考虑代码的维护... ... 相反,尝试这样做:

Public (Class or Structure) MyPerson
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public int ZipCode { get; set; }
End Class

然后:

Dim person as new MyPerson With { .FirstName = “Joe”,
.LastName = "Smith”,
...
}
backgroundWorker1.RunWorkerAsync(person)

然后:

private void backgroundWorker1_DoWork (object sender, DoWorkEventArgs e)
{
MyPerson person = e.Argument as MyPerson
string firstname = person.FirstName;
string lastname = person.LastName;
int zipcode = person.ZipCode;
}