有没有其他更好的方法将参数传递给backgroundworker runasync?

时间:2015-12-04 10:03:46

标签: c# backgroundworker

我是 C#的新手,目前正在开展一个需要BackgroundWorkers的项目。我发现BackgroundWorker RunWorkerAsync只是将一个对象作为参数。但有些情况下我需要将多个对象传递给RunWorkerAsync方法。

我目前所做的是将所有对象加载到List中,然后将它们作为单个List对象传递,该对象工作正常。但我的问题是,这可以做得更好还是更好?我可以用这种方法遇到任何问题吗?

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
}

5 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

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

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()的调用变为:

worker.RunWorkerAsync(() => test("My string", 12345));

答案 2 :(得分:1)

我认为这种方法没有任何重大问题。无论如何,你必须将参数合并为一个。就个人而言,我更喜欢使用tuples的以下方法,它至少需要.NET 4.0:

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

private void DoWork(object sender, DoWorkEventArgs e) {
  var data = e.Arguments as Tuple<objecttype1,objecttype2,objecttype3>;
  var object1 = data.Item1;
  var object2 = data.Item2;
  var object2 = data.Item3;

  //Do stuff
}

在这里你需要更少的演员表,但这不是什么大问题。

答案 3 :(得分:0)

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

创建参数

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();

答案 4 :(得分:-1)

我们始终可以使用我们的自定义列表,请参见下文。

您的自定义类:

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

调用后台工作者:

 backgroundWorker1.RunWorkerAsync(workers);

读取数据:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        List<Worker> workers = e.Argument as List<Worker>;
        //do your code here 
    }