【问题标题】:invoke during background worker在后台工作期间调用
【发布时间】:2012-12-19 20:13:28
【问题描述】:

我需要调用这个:string input_ip_r = listView1.Items[lc].SubItems[1].Text; 所以我用了

if (InvokeRequired)
{
    this.Invoke(new MethodInvoker(function));
    return;
}

这可行,但现在我已将其放入 BackgroundWorker 并使用它

if (InvokeRequired)
{
    this.Invoke(new MethodInvoker(bw.RunWorkerAsync));
    return;
}

它给出了一个错误,您一次只能运行BackgroundWorker

那么我如何在Backgroundworker 中调用呢?

【问题讨论】:

  • 好吧,我很困惑。 a) 为什么将访问 UI 的代码放在后台工作人员中? b) 您是否尝试在 bw.DoWork 内运行 bw.RunWorkerAsync
  • 什么意思?第一个代码应该从后台线程(调用 UI 线程)运行。第二个代码看起来像是在尝试调用后台线程。
  • 字符串需要被调用,我不知道如何在后台工作期间执行此操作,“新 MethodInvoker”尝试第二次运行它

标签: c# background invoke worker


【解决方案1】:

1) 不要将RunWorkerAsync 作为调用的方法。它实际上并没有运行您认为的方法。你真正应该放的东西是这样的:

this.Invoke(new MethodInvoker(MethodToUpdateUI));

MethodToUpdateUI 应该是您创建的一些新方法,专门执行在此上下文中应进行的任何 UI 更新。

2) 不需要InvokeRequired。你在后台线程中。总是需要调用。

说实话,if(invoke required) call myself else do stuff 的整个模式都是我不喜欢的奇怪结构。 InvokeRequired 应该很少使用。你应该几乎总是知道你是在 UI 线程还是后台线程,如果你不知道,很可能有问题(要么你总是在一个或另一个,你只是不知道哪个,或者它不应该是不确定的)。通常这意味着拥有必须在 UI 线程中运行的方法。如果您已经在 UI 线程中,您只需调用它们,如果您在后台线程中并且知道它,那么您首先调用 Invoke

最重要的是,Invoke 工作得很好,即使你已经在 UI 线程中调用它,所以无论你是否在后台线程或已经在 UI 线程中。

3) 通常最好将解决业务问题的代码与 UI 代码分开。从 DoWork 的处理程序中调用是代码异味。如果这即将结束,您可能应该向RunWorkerCompleted 添加一个事件处理程序。如果您定期调用它以使用工作人员的进度更新 UI,您应该使用 ReportProgress 并处理 ProgressReported 事件。要从 UI 获取信息以用于长时间运行的任务,您应该在启动后台任务之前访问它。对于不属于上述任何一种的特殊情况,使用Invoke 可能是合适的,但其余情况应该很少见。

【讨论】:

  • 我需要在没有跨线程调用的后台worker中设置这个值listView1.Items[lc].SubItems[1].Text
  • @user1335937 好的。这就是我的回答正在帮助您解决的问题。
  • 我对 c# 很陌生,所以我有一个循环来从子项 2 中获取每个列表视图项,以及如何在后台工作人员中使用它?
  • @user1335937 从列表视图中取出所有项目并将它们放入数据结构中,例如List 或数组。然后将其存储为私有实例字段并在后台工作人员中使用。这样一来,您就不会从后台工作人员访问 UI。
【解决方案2】:

我不太确定你想如何使用这些值,但举个例子,你可以很容易地在 BackgroundWorker 线程中执行此操作:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    string input_ip_r = "";
    this.Invoke(new Action(() => 
    {
        // Don't know what "lc" is (a loop variable?)
        input_ip_r = listView1.Items[lc].SubItems[1].Text;
    }));
}

请参阅 this answer 了解其他相同方式(适用于 >= .Net 3.5)

【讨论】:

  • 我很高兴它对你有用 =) 但请记住,这只是你可以使用它的方法之一。 @Servy 的回答也有一些值得考虑的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多