Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 接受多个参数的BackgroundWorker的替代方案?_C#_.net_Multithreading_Asynchronous_Backgroundworker - Fatal编程技术网

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

C# 接受多个参数的BackgroundWorker的替代方案?,c#,.net,multithreading,asynchronous,backgroundworker,C#,.net,Multithreading,Asynchronous,Backgroundworker,BackgroundWorker对象允许我们将单个参数传递给DoWorkEventHandler // setup/init: BackgroundWorker endCallWorker = new BackgroundWorker(); endCallWorker.DoWork += new DoWorkEventHandler(EndCallWorker_DoWork); ... endCallWorker.RunWorkerAsync(userName); // the handler

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;
    ...
}
要传递多个参数,我必须将它们包装在一个对象中,就像下面这个糟糕的字符串数组:

// 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];
}
是否有另一个对象或模式允许我们很好地传递多个参数,或者理想情况下,编写我们自己的签名

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

您可以使用闭包(Lambda):

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


也许传递一个lambda函数作为你的对象?然后你会把它称为道具处理程序

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

对象可以是列表、数组或类似的对象。只需将对象设置为某种容器,然后在BackgroundWorker中强制转换即可。您需要确保始终传递相同的类型。

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

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

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

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

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

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;
}

你能详细说明一下这是怎么回事吗?(特别是“(s,e)”…为什么要声明它们?)我非常喜欢这个-对于我的用例来说,它工作得很好,但更复杂的应用程序可能会有问题,即我需要访问setup/init上的参数值(username和targetNumber)。我很乐意提供帮助(还有更多文本)。我认为这个解决方案中的警告是,我们失去了在DoWorkEventArgs e中填充结果或取消字段的能力。如果您不打算以任何方式使用它,那就太好了。@Samik R您不能这样做以保留结果:(s,e)=>e.result=MyWorkMethod(userName,targetNumber)+如果库设计人员处理了两个参数,为什么不处理三个、四个,等等?解决方案是处理一个类,这个类可以是任意复杂度的对象。这比我的string[]数组好,但仍然-我不想声明另一个类只是为了将参数传递到我自己的函数中。这种情况在.NET中的许多其他内置处理程序中都会发生-我想我正在寻找一种一致的模式,它不会用无用的包装类污染我的代码。C#4.0有一个元组,它可以容纳多个参数。请参阅我对这个问题的回答。
internal class UserArgs
{
    internal string UserName { get; set; }
    internal string TargetNumber { get; set; }
}

var args = new UserArgs() {UserName="Me", TargetNumber="123" };
startCallWorker.RunWorkerAsync(args);
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;
}