【问题标题】:control.BeginInvoke() Vs Dispatcher Vs SynchronizationContext Vs .. - RELIABILITYcontrol.BeginInvoke() Vs Dispatcher Vs SynchronizationContext Vs .. - 可靠性
【发布时间】:2011-09-14 00:06:31
【问题描述】:

从工作线程调用 UI 线程被讨论过很多次,我们知道为什么要使用 BeginInvoke() 而不是 Invoke()。我最近发布了this question,在进行了一些研究后,我发现至少有三种不同的方式(在内部它们可能相同)在 UI 线程上调用(异步)某些东西。

  1. Control.BeginInvoke()
  2. 使用SynchronizatoinContext
  3. 使用Dispatcher.BeginInvoke(priority.. )

谁能告诉我异步调用要在 UI 线程上执行的方法的可靠方法。有什么经验吗?我看到 Dispatcher.BeginInvoke 具有优先级组件,它是否使它更可靠?

上下文
我们正在使用someControl.BeginInvoke(),但注意到有时(不幸的是仅在最终用户生产环境中)传递给BeginInvoke is 的委托从未执行过,这让我相信它创建的发布消息正在丢失。我们想要一种可靠的方式与 UI 线程进行通信。 control.Invoke() 有时会挂起 UI,所以我们也不想去那里。

【问题讨论】:

  • 不要将 WinForms 与 WPF 混淆。
  • 我遇到了类似的问题...您是否设法纠正了问题?
  • 这里一样,有更新吗?

标签: c# delegates


【解决方案1】:

您应该小心使用 lambda 函数和 BeginInvoke。我有这样的代码导致各种奇怪的行为。

MyThing thing;
while( GetThing(ref thing)) {
    control.BeginInvoke((Action)(() => control.Text = thing.ToString()));
}

问题是thing 在您创建 lambda 函数时不会被计算。在执行 lamdba 函数时对其进行评估。但它绑定了一个在生产者线程中同时发生变化的变量。

您可以通过声明thing 的局部变量副本来解决此问题

MyThing thing;
while( GetThing(ref thing)) {
  MyThing thing_x = thing;
  control.BeginInvoke((Action)(() => control.Text = thing_x.ToString()));
}

或者您可以将 BeginInvoke 丑陋放在一个包装器中

MyThing thing;
while( GetThing(ref thing)) {
  SetText(thing);
}

void SetText(MyThing thing)
  control.BeginInvoke((Action)(() => control.Text = thing.ToString()));
}

【讨论】:

    【解决方案2】:

    SynchronizationContext 在更多情况下更加抽象和适应性强。它是特定实现的包装器。 MSDN 说“同步模型的提供者可以扩展这个类并为这些方法提供他们自己的实现”。

    【讨论】:

    【解决方案3】:

    它们都按应有的方式运行,如果您调用BeginInvoke 并且有时没有任何反应,则可能是环境或调用代码存在问题-并不是BeginInvoke 不可靠。嗯 - 可能存在错误,但可能性要小得多。

    也许您可以提供更多背景信息,我们可以帮助诊断。

    【讨论】:

    • 感谢您的回复。我的代码中有类似的场景。 stackoverflow.com/questions/6270514/…
    • 嗨,karephul,这很有趣,但在这种情况下并没有太大帮助,因为他们也没有找到答案。您在线程、进程、锁等方面的基本设置是什么?
    • 哦...是同样的问题吗?刚刚在这里转贴?
    • 另一个例子中你的逻辑有缺陷。如果 UI 线程出现异常,executing 将保持为true,并且不再调用该方法。也许这就是正在发生的事情。
    猜你喜欢
    • 1970-01-01
    • 2013-01-23
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 2021-02-27
    相关资源
    最近更新 更多