- 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/
我看了很多文章,但我仍然不清楚我们通常创建的普通委托(delegate)和多播委托(delegate)之间的区别。 public delegate void MyMethodHandler(objec
考虑以下几点: Action a1 = new Action(_insert); Action a2 = new Action(a1); a2 指的是什么?它是 a1,a1 的浅拷贝还是 a1 的深拷
我希望这听起来像是一个显而易见的问题,但是委托(delegate)返回类型是否也必须与其委托(delegate)的方法的返回类型相匹配? EG,像这样: public static void Save
我想使用 Kotlin 委托(delegate),但我不想在委托(delegate)人之外创建委托(delegate)。委托(delegate)的所有示例都如下所示: interface Worker
class SuperClass { var delegate : SuperClassDelegate? } protocol SuperClassDelegate { func d
我有一个加载 View 的 View ,需要将 View 推送到主导航 Controller 。 我已经为每个 View 设置了一个委托(delegate),并且基本上使我的调用沿着“链”返回到主导航
为简单起见,假设我想创建一个自定义 UITextField 并向其添加一个简单的行为;也就是说,如果文本字段成为第一响应者,背景颜色将变为绿色。 为此,在我的自定义类中,我必须将该类设置为委托(del
我非常有信心我应该能够使用非静态方法的委托(delegate),但下面给了我一个错误: public class TestClass { private delegate void TestD
在 C# 中不能从 System.Delegate 或 System.MulticastDelegate 继承。只要您声明标准的“运行时托管”方法,就完全可以在 MSIL 中执行此操作。但是,每次我向
我在 Storyboard 中定义了一个 iPad 界面,带有一个 SplitViewController。我想将 SplitViewController 的委托(delegate)设置为指向详细 C
我有几个解析器。有一个顶级的可以委托(delegate)给另一个。 Parser我们从 Reader 中获取他们的输入(可变)。我只想要一个 Parser为了能够一次解析,只有一个解析器应该有 Rea
一直以来我都在阅读关于反射的文章,每个人都在说:“反射很慢”,“反射很慢”。 现在我决定测试速度有多慢,令我惊讶的是,使用反射创建的委托(delegate)实际上是使用 lambda 创建的委托(de
在 Xcode 4.5 中启动了 Cocos2D 2.1 模板(没有物理引擎),针对 iOS 6 和 iPad。在 CDAudioManager.m 文件中,以下代码... AVAudioSessio
以下是来自未管理的 dll 的函数代码。它接受一个函数指针作为参数,并简单地返回被调用函数返回的值。 extern __declspec(dllexport) int _stdcall callDe
//NewCharts.h #import @interface NewCharts : UIViewController @property(nonatomic,retain)IBOutlet U
鉴于以下 MSDN 示例代码,为什么我不能定义 Action 委托(delegate)“内联”: public static void Main(string[] args) { Action
在虚幻引擎中,UFUNCTION用于通过附加说明符来丰富功能,以用于蓝图使用、复制和委托(delegate)。 然而,一些委托(delegate)类型似乎不允许绑定(bind) UFUNCTION(如
我刚刚将照片选择器放入我的项目中,一切正常。唯一的事情是它坚持在我设置委托(delegate)的地方给我以下警告 - Assigning to 'id' from incompatible type
我有一个 UIImageView 的子类,并且想将 self 作为参数传递给委托(delegate)。我在 MyImageView 之前收到错误“预期 ')'”。我需要将对象传递给委托(delegat
我正在开发 iOS 10 的语音转文本功能。 我希望调用 SFSpeechRecognitionTaskDelegate 的委托(delegate)方法来检查完成的结果。 func speechRec
我是一名优秀的程序员,十分优秀!