【问题标题】:Is there any other better way to pass parameters to backgroundworker runasync?还有其他更好的方法可以将参数传递给 backgroundworker runasync 吗?
【发布时间】:2020-07-31 23:59:24
【问题描述】:

我是 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
}

【问题讨论】:

  • 将它们定义为私有属性,然后在启动 worker 之前分配值。您可以在 DoWork 方法中访问这些属性中的值。
  • @KosalaW 他可以做到这一点,但这是一种错误的方法。当他可以简单地使用包装类作为参数时,他为什么要使用全局变量并在实例和工作逻辑之间建立依赖关系(这更干净)。
  • 这取决于要求。包装类只是另一种方式。但是,如果您的表单中已经有这些属性,为什么不使用它们呢?大多数时候,您必须在多个地方使用这些属性。但是,如果您的表单中没有它们(这不太可能),那么可以创建一个专门作为参数传入的类。

标签: c# backgroundworker


【解决方案1】:

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

【讨论】:

  • 感谢 i486 :) 我可以用 2 个对象离开它,但如果我有更多对象,我肯定会为它们创建一个类。
【解决方案2】:

作为在类中包装参数的替代方法,您可以改为使用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() 的调用就变成了:

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

【讨论】:

  • @Mathew 非常感谢您的详细回答。由于我的经验水平,看起来有点中国,但我会学习:)
【解决方案3】:

我认为这种方法没有任何大问题。在任何情况下,您都必须将这些论点合二为一。就个人而言,我更喜欢使用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
}

在这里你需要更少的演员,但这没什么大不了的。

【讨论】:

    【解决方案4】:

    这是我如何传递多个参数

    -创建参数

    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,您可以传递强类型对象。无论如何,BGW 已经过时了。您可以使用 Task.Runasync/await 执行相同的操作,另外还可以链接多个异步操作
    【解决方案5】:

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

    您的自定义类:

    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 
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-19
      • 2020-04-17
      • 2012-10-08
      • 1970-01-01
      • 2018-05-22
      • 1970-01-01
      • 2015-10-01
      • 2012-12-26
      相关资源
      最近更新 更多