后台工作线程

Background workers

提问人:funerr 提问时间:10/7/2011 最后编辑:Joe Whitefunerr 更新时间:10/7/2011 访问量:286

问:

我制作了一种方法,列出路径中的所有ftp文件夹。
我的问题是我需要将其作为数组返回。
但它是一个后台工作程序,我只能
用 e.Result 将其返回给“RunWorkerCompleted”。
1) 如何将参数传递给方法?(后台工作人员)
2)如何将文件夹数组恢复为普通方法?
这样:

private void btnOpen_Click_1(object sender, EventArgs e)
        {
           string[]/List... a=  getDirectories(**path**)?
        }
C# backgroundworker 参数传递 返回类型

评论


答:

0赞 Andras Zoltan 10/7/2011 #1

您可以将 List 作为表单本身的成员,并让工作人员在执行其工作时将其添加到其中(由于工作人员代码将属于表单,因此该成员将在范围内)。

因此,如果您希望工作人员将其项目添加到列表的特定实例中;只需在触发 worker 之前先将其设置到 Member 中即可。

但是,使用此方法时必须小心,不要在辅助角色运行时访问该列表;因为它不是线程安全的。在 .Net 4 中,可以使用线程安全的 ConcurrentBag

如果您不想这样做,那么正如您所说,事件中传递的事件参数的成员将用于传达结果 - 这就是您将返回列表的位置。您还可以使用该事件(在 MSDN 上)流式传输结果的单个快照。ResultRunWorkerCompletedProgressChanged

我不认为这是不合理的:异步操作与同步调用是根本不同的范式,你根本不能使用相同的调用和返回语义。

评论

0赞 funerr 10/7/2011
是的,我想到了。但是我想每次都将数组返回给特定方法......而不是 RunWorkerCompleted。
0赞 user586399 10/7/2011 #2

您可以传递参数,因为它们是对象。BackgroundWorker 采用的参数为 。的变量可以携带任何东西:数组、引用和变量。objectobject

例:

object[] args = new object[] { fileName, ....... };
this.backgroundWorker1.RunWorkerAsync(args);

在方法中:

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            object o = e.Argument;
            object[] args = (object[])o;
            string fileName = (string)args[0];
            ....
            object[] result = ....
            e.Result = result;
        }

工作完成后:

void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

            object o = e.Result;
            object[] result = (object[])o;
            ...
        }

评论

0赞 funerr 10/7/2011
问题是我正在创建一个下载目录中所有文件的方法,并且我正在使用递归,然后我需要将数组返回给该方法,而不是返回给 RunWorkerComplete。
0赞 10/7/2011
@askingDude 你能展示你的代码吗?我什么都不懂
0赞 funerr 10/8/2011
谢谢,但我现在正在尝试使用线程,也许它们会奏效。如果没有,我会发布我的代码。