C# 接受多个参数的 BackgroundWorker 的替代方案?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1145780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:18:52  来源:igfitidea点击:

Alternative to BackgroundWorker that accepts more than one argument?

c#.netmultithreadingasynchronousbackgroundworker

提问by Jeff Meatball Yang

The BackgroundWorker object allows us to pass a single argument into the DoWorkEventHandler.

BackgroundWorker 对象允许我们将单个参数传递给 DoWorkEventHandler。

// setup/init:
BackgroundWorker endCallWorker = new BackgroundWorker();
endCallWorker.DoWork += new DoWorkEventHandler(EndCallWorker_DoWork);
...
endCallWorker.RunWorkerAsync(userName);

// the handler:
private void EndCallWorker_DoWork(object sender, DoWorkEventArgs e)
{
    string userName = e.Argument as string;
    ...
}

To pass multiple arguments, I must wrap them in an object, like this poor string array:

要传递多个参数,我必须将它们包装在一个对象中,就像这个糟糕的字符串数组:

// setup/init:

BackgroundWorker startCallWorker = new BackgroundWorker();
startCallWorker.DoWork += new DoWorkEventHandler(StartCallWorker_DoWork);
...
startCallWorker.RunWorkerAsync(new string[]{userName, targetNumber});


// the handler:
private void StartCallWorker_DoWork(object sender, DoWorkEventArgs e)
{
    string[] args = e.Argument as string[];
    string userName = args[0];
    string targetNumber = args[1];
}

Is there another object or pattern that allows us pass multiple arguments nicely, or ideally, write our own signature?

是否有另一个对象或模式允许我们很好地传递多个参数,或者理想情况下,编写我们自己的签名?

采纳答案by Ben M

You could use a closure (Lambda):

您可以使用闭包(Lambda):

backgroundWorker.DoWork += (s, e) => MyWorkMethod(userName, targetNumber);

Or with delegate (anonymous method) syntax:

或者使用委托(匿名方法)语法:

backgroundWorker.DoWork += 
    delegate(object sender, DoWorkEventArgs e)
    {
        MyWorkMethod(userName, targetNumber);
    };

回答by Kenan E. K.

Why not have the "one" object passed be an array of parameters? You only need to cast it back to array inside the method from the object parameter.

为什么不将“一个”对象传递为参数数组?您只需要将它从对象参数转换回方法内的数组。

回答by Sam Harwell

Maybe pass a lambda function as your object? Then you'd call it in the DoWork handler.

也许传递一个 lambda 函数作为你的对象?然后你会在 DoWork 处理程序中调用它。

endCallWorker.RunWorkerAsync(new Action( () => DelegatedCallTarget(userName, targetNumber) ));

回答by McAden

Object can be a list or array or some such. Just make your object a container of some sort, then cast within the BackgroundWorker. You need to make sure you're always passing in the same type though.

对象可以是列表或数组等。只需让您的对象成为某种容器,然后在 BackgroundWorker 中进行转换。不过,您需要确保始终传递相同的类型。

回答by Vijay Patel

What's wrong with using a typed object?

使用类型化对象有什么问题?

internal class UserArgs
{
    internal string UserName { get; set; }
    internal string TargetNumber { get; set; }
}

var args = new UserArgs() {UserName="Me", TargetNumber="123" };
startCallWorker.RunWorkerAsync(args);

回答by Peter Long

instead of a typed object. C# 4.0 provides us with tuple. We could use a tuple to hold multiple args. Then there is no need to declare a new class.

而不是类型化的对象。C# 4.0 为我们提供了元组。我们可以使用一个元组来保存多个参数。那么就不需要声明一个新的类了。

回答by Azhar Khorasany

Create a class that holds all your arguments

创建一个包含所有参数的类

Class MyClass
{
     private string m_Username = string.Empty;
     private int m_Targetnumber;

     public MyClass(){}

     public string Username
     {
         get { return m_Username; }
         set { m_Username = value; }
     }

     public int TargetNumber
     {
         get { return m_TargetNumber; }
         set { m_TargetNumber = value; }
     }
 }



// setup/init:

BackgroundWorker startCallWorker = new BackgroundWorker();
startCallWorker.DoWork += new DoWorkEventHandler(StartCallWorker_DoWork);
...

MyClass thisClass = new MyClass();
thisClass.Username = "abcd";
thisClass.TargetNumber = 1234;
startCallWorker.RunWorkerAsync(thisClass);


// the handler:
private void StartCallWorker_DoWork(object sender, DoWorkEventArgs e)
{
     MyClass args = (MyClass)e.Argument;
     string userName = args.Username;
     string targetNumber = args.TargetNumber;
}