C# 是否有其他更好的方法将参数传递给backgroundworker runasync?

C# 是否有其他更好的方法将参数传递给backgroundworker runasync?,c#,backgroundworker,C#,Backgroundworker,我是新来的C#,目前正在从事一个需要。我发现BackgroundWorker只是将一个对象作为参数。但在某些情况下,我需要将多个对象传递到方法中 我现在要做的是将所有对象加载到一个列表中,然后将它们作为一个列表对象传递,这样就可以了。但我的问题是,这能做得更好或更好吗?使用这种方法是否会遇到任何问题 List<object> data = new List<object>(3); List.Add(object1); List.Add(object2); List.Ad

我是新来的C#,目前正在从事一个需要。我发现BackgroundWorker只是将一个对象作为参数。但在某些情况下,我需要将多个对象传递到方法中

我现在要做的是将所有对象加载到一个列表中,然后将它们作为一个列表对象传递,这样就可以了。但我的问题是,这能做得更好或更好吗?使用这种方法是否会遇到任何问题

List<object> data = new List<object>(3);

List.Add(object1);
List.Add(object2);
List.Add(object3);

bwImportData.RunWorkerAsync(data);

private void DoWork(object sender, DoWorkEventArgs e)
{
   List<object> data = e.Arguments a List<object>
   objecttype1 object1 = data[0] as objecttype1;
   objecttype2 object2 = data[0] as objecttype2;
   objecttype3 object2 = data[0] as objecttype3;

   //Do stuff

}
private void RunWorker(object sender, RunWorkerCompletedEventArgs e)
{
   //Do stuff stuff stuff
}
列表数据=新列表(3);
添加(object1);
添加(object2);
添加(object3);
bwinmportdata.RunWorkerAsync(数据);
私有无效DoWork(对象发送方,DoWorkEventArgs e)
{
列表数据=e.参数列表
objecttype1 object1=作为objecttype1的数据[0];
objecttype2 object2=数据[0]作为objecttype2;
objecttype3 object2=数据[0]作为objecttype3;
//做事
}
私有void RunWorker(对象发送方,RunWorkerCompletedEventArgs e)
{
//做事
}

您可以为参数定义结构/类,创建该类型的对象,填充参数,并将其作为对象参数发送。稍后直接从对象中使用它们,而不是像您的示例中那样,将var object1=data[0]复制为objecttype1

我认为这种方法没有什么大问题。在任何情况下,您都必须将参数组合成一个参数。就个人而言,我更喜欢使用以下方法,至少需要.NET 4.0:

bwImportData.RunWorkerAsync(new Tuple.Create(object1,object2,object3));

private void DoWork(对象发送方,DoWorkEventArgs e){
var data=e.作为元组的参数;
var object1=data.Item1;
var object2=data.Item2;
var object2=data.Item3;
//做事
}

这里您需要较少的强制转换,但这并不是什么大问题。

作为在类中包装参数的替代方法,您可以使用
Action()
作为参数,并将参数强制转换回
DoWork
处理程序中的
Action
,如下所示:

using System;
using System.ComponentModel;

namespace Demo
{
    class Program
    {
        static void Main()
        {
            var worker = new BackgroundWorker();

            worker.DoWork += (sender, args) => ((Action) args.Argument)();

            worker.RunWorkerAsync(new Action(() => test("My String", 12345)));

            Console.ReadLine();
        }

        static void test(string s, int i)
        {
            Console.WriteLine("String = {0}, Int = {1}", s, i);
        }
    }
}
通过编写如下扩展方法,可以使其更易于阅读:

public static class BackgroundWorkerExt
{
    public static void RunWorkerAsync(this BackgroundWorker worker, Action action)
    {
        worker.RunWorkerAsync(action);
    }
}
然后,对RunWorkerAsync()的调用变为:


下面是我如何传递多个参数

-创建参数

object obje10 = imageList[i];
object obje11 = i;
object obje12 = product_Name;

object[] parameters = new object[3] { obje10, obje11, obje12};
-使用RunWorkerAsync发送参数

worker.RunWorkerAsync(parameters);
-然后在DoWork方法中获取参数

object[] parameters = e.Argument as object[];
List<Image> imgs = parameters[0] as List<Image>;
int i = (int)parameters[1];
string product_Name = parameters[2].ToString();
object[]参数=e.作为object[]的参数;
将imgs=参数[0]列为列表;
int i=(int)参数[1];
字符串product_Name=参数[2]。ToString();

我们可以随时处理我们的自定义列表,请参见下文

您的自定义类:

public class Worker
{
    public int Id { get; set; }
    public string Comments { get; set; }
}
列表创建:

List<Worker> workers = new List<Worker>()
{
   new Worker { Id = 1, Comments = "hello" }
};
阅读您的数据:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        List<Worker> workers = e.Argument as List<Worker>;
        //do your code here 
    }
private void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
List workers=e.参数为List;
//请在这里输入您的代码
}

将它们定义为私有属性,然后在启动worker之前分配值。您可以在
DoWork
方法中访问这些属性中的值。@KosalaW他可以这样做,但这是一种错误的方法。为什么他会使用全局变量并在实例和工作逻辑之间建立依赖关系,而他可以简单地使用包装类作为参数(这要干净得多)。这取决于需求。包装器类只是另一种方法。但是,如果您已经在表单中提供了这些属性,为什么不使用它们呢?大多数情况下,您必须在多个位置使用这些属性。但是,如果您的表单中没有这些参数(这是不太可能的),那么可以创建一个专门作为参数传入的类。@Mathew非常感谢您提供了这个详细的答案。由于我的经验水平,我看起来有点中文,但我会学习:)谢谢i486:)我可以用两个物体来完成,但如果我有更多的物体,我肯定会为它们制作一个课程。这和所有其他答案一样。您也不需要将值包装为
object
,您可以传递强类型对象。在任何情况下,BGW都是过时的。您可以对
任务执行相同的操作。运行
异步/await
,这样做的额外好处是您可以链接多个异步操作
List<Worker> workers = new List<Worker>()
{
   new Worker { Id = 1, Comments = "hello" }
};
 backgroundWorker1.RunWorkerAsync(workers);
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        List<Worker> workers = e.Argument as List<Worker>;
        //do your code here 
    }