control.BeginInvokeVs调度程序Vs SynchronizationContext Vs ..-可靠性

问题描述

| 从工作线程调用UI线程的讨论很多次,我们知道为什么要使用BeginInvoke()而不是Invoke()。我最近发布了这个问题,经过研究后发现,至少有三种不同的方法(内部可能是相同的)来调用(异步)UI线程上的某些东西。
Control.BeginInvoke()
使用
SynchronizatoinContext
课 使用
Dispatcher.BeginInvoke(priority.. )
谁能告诉我哪种方法是异步调用要在UI线程上执行的方法的可靠方法。有经验吗?我看到Dispatcher.BeginInvoke具有优先级组件,它使它更可靠吗? 内容: 我们使用的是
someControl.BeginInvoke()
,但注意到有时(不幸的是,仅在最终用户生产环境中)传递给
BeginInvoke is
的委托从未执行,这使我相信它所创建的发布消息会丢失。我们想要一种可靠的方法来与UI线程通信。
control.Invoke()
有时会挂起UI,所以我们也不想去那里。     

解决方法

        它们都按应有的方式工作,如果您呼叫
BeginInvoke
,有时什么也没发生,则环境或调用代码中可能存在一些问题-
BeginInvoke
不是不可靠。好吧-可能有一个错误,但是可能性很小。 也许您可以提供更多背景信息,我们可以帮助您进行诊断。     ,        在更多情况下,SynchronizationContext更抽象且更具适应性。它是特定实现的包装。 MSDN说:“同步模型的提供者可以扩展此类,并为这些方法提供自己的实现”。     ,        您应谨慎使用lambda函数和BeginInvoke。我有这样的代码,导致各种奇怪的行为。
MyThing thing;
while( GetThing(ref thing)) {
    control.BeginInvoke((Action)(() => control.Text = thing.ToString()));
}
问题在于创建lambda函数时不会评估ѭ9。当执行lamdba函数时将对其进行评估。但是它绑定到在生产者线程中同时更改的变量。 您可以通过声明局部变量ѭ9来解决此问题。
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()));
}
    

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...