- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是否有 Control.BeginInvoke() 不执行传递给它的委托(delegate)的解释?
我们在 Winforms 应用程序中采用了以下模式,以在 UI 线程上安全地执行与 UI 相关的工作:
private Control hiddenControl = new Control();
private void uiMethod()
{
MethodInvoker uiDelegate = new MethodInvoker(delegate()
{
Logging.writeLine("Start of uiDelegate");
//ui releated operations
childDialog = new ChildDialog();
childDialow.show();
Logging.writeLine("End of uiDelegate");
});
if (hiddenControl.InvokeRequired)
{
Logging.writeLine("Start of InvokeRequired block");
hiddenControl.BeginInvoke(uiDelegate);
Logging.writeLine("End of InvokeRequired block");
}
else
{
uiDelegate();
}
}
在这里,我们明确创建了一个控件“hiddenControl”,用于在 UI 线程上运行委托(delegate)。我们从不调用 endInvoke 因为它显然是 not required对于 Control.BeginInvoke,我们永远不需要返回值,因为无论如何我们的方法只是操纵 UI。
虽然非常冗长,但这个模式似乎是一个 relatively well accepted solution .然而,有一些evidence即使是这种模式也可能无法在所有情况下都适用。
我不排除应用程序错误并责怪 WinForms。毕竟,select probably isn't broken .然而,我无法解释为什么代表似乎根本不参选。
在我们的案例中,我们有时会观察到“Start of uiDelegate”日志消息在某些线程场景中永远不会执行,即使“Start of InvokeReqiured block”和“End of InvokeRequired block”成功执行也是如此。
复制这种行为非常困难,因为我们的应用程序是作为 DLL 交付的;我们的客户在他们自己的应用程序中运行它。因此,我们无法保证如何或在哪个线程中调用这些方法。
我们排除了 UI 线程饥饿,因为观察到 UI 没有锁定。据推测,如果正在更新 UI,则消息泵可以运行并可用于从消息队列中提取消息并执行它们的委托(delegate)。
根据这些信息,我们可以尝试做些什么来使这些调用更加可靠?如前所述,我们对给定应用程序中的其他线程的控制相对较少,并且不控制调用这些方法的上下文。
还有什么可以影响委托(delegate)如何成功传递给 Control.BeginInvoke() 执行或不执行?
最佳答案
根据 MSDN即使在 InvokeRequired
应该是 true
的情况下,InvokeRequired
也可以返回 false
- 即在您访问 的情况下>InvokeRequired
在创建该控件/窗体(或其父级)的 Handle
之前。
基本上您的检查不完整导致您看到的结果。
你需要检查IsHandleCreated
- 如果那是 false
那么你就有麻烦了,因为 Invoke
/BeginInvoke
是必需的,但由于 Invoke 而无法正常工作
/BeginInvoke
检查哪个线程创建了 Handle
来发挥它们的魔力...
只有当 IsHandleCreated
为 true
时,您才会根据 InvokeRequired
返回的内容采取行动 - 类似于:
if (control.IsHandleCreated)
{
if (control.InvokeRequired)
{
control.BeginInvoke(action);
}
else
{
action.Invoke();
}
}
else
{
// in this case InvokeRequired might lie - you need to make sure that this never happens!
throw new Exception ( "Somehow Handle has not yet been created on the UI thread!" );
}
因此,以下内容对于避免此问题很重要
始终确保在 UI 线程以外的线程上首次访问之前已经创建了 Handle
。
根据 MSDN您只需要在 UI 线程中引用 control.Handle
以强制创建它 - 在您的代码中,这必须在您第一次从非 UI 的任何线程访问该控件/表单之前发生线程。
对于其他可能性,请参阅@JaredPar 的回答。
关于c# - Control.BeginInvoke 不执行委托(delegate)的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8978573/
我对 Dispatcher.CurrentDispatcher.BeginInvoke 和 BeginInvoke 之间的区别感到困惑 我有以下部分代码不起作用,UpdateCounts 方法中的代码
我最初尝试使用 Dispatcher 类 BeginInvoke 方法在我的 C# Windows 窗体应用程序的主 UI 线程上显示消息框。当我使用该方法时,消息框没有出现。我在传递给 BeginI
伙计们! 我的.net应用程序有问题。当我尝试在程序中打印时,它会崩溃崩溃 与任何错误消息。我从Windows中的事件查看器中获得的有关错误的信息。有人能帮我吗?但是在另一台计算机上它可以正常工作。我
我有简单的(我认为的)逻辑。 public static void NotifyAboutNewJob(int jobId, bool forceSending = false) {
我有一个 c# .NET winforms 应用程序进行此异步调用: simpleDelegate.BeginInvoke(null, null); 委托(delegate)正在调用我的函数,一切正常
1) 我听说当我们不调用 EndInvoke() 时可能会导致内存泄漏?你能演示一下这怎么会导致内存泄漏吗? 2) 当我想调用 EndInvoke() 时,我应该使用如下代码吗? namespace
我遇到了在多线程应用程序中使用 Dispatcher.BeginInvoke 导致的我无法理解的错误。 我的程序包含一个 List 对象,我使用多个线程循环遍历这些对象并执行一些计算。我已将我的代码结
我正在研究其他人的代码,但对多线程没有太多经验。我遇到了这行代码: BeginInvoke((MethodInvoker)delegate() { btnCalibrate.PerformClick(
我继承了从主线程调用 BeginInvoke 的代码(不是后台线程,通常是这种模式)。我试图了解它在这种情况下的实际作用。 在 BeginInvoke 中调用的方法是否符合下行到窗口的消息?文档说 a
为什么会出现此错误以及如何修复它。感谢帮助 错误 4 无法将 lambda 表达式转换为类型“System.Delegate”,因为它不是委托(delegate)类型 void provide
我在 WPF 应用程序中有一些代码如下所示: public class MyTextBox : System.Windows.Controls.TextBox, IDisposable { p
我有以下问题。 FindRoot 实际上在第三方 dll 中,我无法控制它。 它必须通过 Begin invoke 调用。有时,FindRoot 方法会抛出异常。这导致我的整个应用程序崩溃。现在,即使
这个问题在这里已经有了答案: Does Func.BeginInvoke use the ThreadPool? (2 个答案) 关闭 1 年前。 在我的 WPF 应用程序中,我想在非 UI 线程中
我是线程和异步编程的新手。我正在尝试学习这些概念,到目前为止,我已经理解了,但是还有一个问题要问。 可以说我想调用一个名为GetAllUsers()的方法,该方法需要很长时间才能执行,因此它不会阻塞资
我已经看到(并阅读)关于使用 Dispatcher.BeginInvoke 来确保 UI 更新发生在 UI 线程上。我明白这个道理。 但是我看到了在 View 代码隐藏中分配属性(例如 TextBlo
我想确定使用 BeginInvoke 时执行处理程序的线程。现在,每次我调用该方法时,处理程序都会由不同的线程执行。有没有办法确定线程? using System; using System.Thre
我有一个长时间运行的函数¹: public string FindPasswordFromHash(String hash) { ... } 它被称为: private void Button
我找不到这个简单问题的答案:BeginInvoke() 是否保证以原子方式执行被调用的委托(delegate)?例如,如果我有类似的东西 public ObservableCollection Ite
我收到一个 InvalidOperationException 消息 Cross-thread operation not valid.. _waitForm 是在主窗体的构造函数中创建的。屏幕截图中
我是编码新手,在我的第一个项目中,我必须从数显卡尺读取信息并将其显示在网络应用程序的文本框中。我从另一个项目中找到了代码,其他人在他们使用 Windows 窗体的地方创建了这些代码。我正在使用 vis
我是一名优秀的程序员,十分优秀!