Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# BeginInvoke()调用延迟_C#_.net_Multithreading - Fatal编程技术网

C# BeginInvoke()调用延迟

C# BeginInvoke()调用延迟,c#,.net,multithreading,C#,.net,Multithreading,我在控制方面遇到问题。BeginInvoke并非每次都发生。它似乎可以正常工作5次左右,然后在那之后,成功率就变成了50/50 正在发生的是,我将在已经创建并显示的控件上调用BeginInvoke,并且不会立即在GUI线程上执行该调用。调用线程确实会立即从BeginInvoke返回并继续其业务。在控件上执行另一个BeginInvoke之前,不会在GUI线程上执行委托。然后,它就好像意识到自己有事情要做,并最终做到了。这可能会在10分钟后发生 代码 下面是执行BeginInvoke的代码,它不会立

我在控制方面遇到问题。BeginInvoke并非每次都发生。它似乎可以正常工作5次左右,然后在那之后,成功率就变成了50/50

正在发生的是,我将在已经创建并显示的控件上调用BeginInvoke,并且不会立即在GUI线程上执行该调用。调用线程确实会立即从BeginInvoke返回并继续其业务。在控件上执行另一个BeginInvoke之前,不会在GUI线程上执行委托。然后,它就好像意识到自己有事情要做,并最终做到了。这可能会在10分钟后发生

代码

下面是执行BeginInvoke的代码,它不会立即执行委托:

protected void DisplayPrompt(PromptData promptData)
{
    Debug.WriteLine(DateTime.Now + ": Entering DisplayPrompt: " + Thread.CurrentThread.Name);
    this.CurrentPrompt = promptData;

    if (this.InvokeRequired)
    {
        Debug.WriteLine(DateTime.Now + ": Before BeginInvoke of DisplayPrompt: " + Thread.CurrentThread.Name);
        this.BeginInvoke(new Action(() => this.DisplayPrompt(promptData)));
        Debug.WriteLine(DateTime.Now + ": After BeginInvoke of DisplayPrompt: " + Thread.CurrentThread.Name);
        return;
    }

    // The rest of the method goes here
}
当执行下面的代码时,调用的方法似乎通过消息泵启动。在我厌倦了等待上面的委托被执行之后,这个代码被执行,我按下一个按钮,最终调用ClearPrompt

最后,这里是输出:

11/13/2013 1:16:49 PM: Entering DisplayPrompt: BatchStateMachine
11/13/2013 1:16:49 PM: Before BeginInvoke of DisplayPrompt: BatchStateMachine
11/13/2013 1:16:49 PM: After BeginInvoke of DisplayPrompt: BatchStateMachine
The thread 0x998 has exited with code 0 (0x0).
The thread 0x1174 has exited with code 0 (0x0).
11/13/2013 1:27:01 PM: Entering ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: Before BeginInvoke of ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: After BeginInvoke of ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: Entering DisplayPrompt: 
11/13/2013 1:27:01 PM: Entering ClearPrompt: 
这是下午1:27:01第二次进入DisplayPrompt,GUI最终在这里运行委托

问题: 所以我想问题是,是什么导致BeginInvoke出现这种延迟行为,我可以做些什么来更好地调试它

其他说明:

这些方法属于UserControl对象的实例 UserControl对象已经存在,并且在代码运行之前已经显示了几分钟,即控制句柄应该存在。 我曾经多次成功地使用BeginInvoke,就像这样 GUI似乎在应该运行委托的时间段内完全响应。GUI控件正在更新,我可以导航应用程序等。
谢谢

多亏了亚当·马拉斯的评论,我相信我已经找到了问题的根源。确实有大量BeginInvoke调用正在执行,但这并不是很明显。我有另一个控件,它从后台线程接收大量更新。正常情况下不足以引起问题,但问题是该控件的实例数量越来越多,它们都在接收更新并执行BeginInvoke以更新GUI

控件数量不断增加的原因是,当导航离开该视图时,应该销毁实例,当返回该视图时,应该重新创建实例。但是,这些控件没有被销毁,因为它们已从长期存在的类实例中注册了更新事件,并且在从窗体中删除控件时没有从事件中注销。这导致长期存在的类持有对相关UserControl实例的引用,并且所有实例将继续处理事件并更新GUI,即使它们不再可见

因此,尽管GUI在某种程度上仍然有响应,但它无法完成所有传入的异步调用。我了解到SendMessage消息实际上并不像PostMessage消息那样被添加到消息队列中,而是直接由消息泵执行,并且比由PostMessage填充的消息队列具有更高的优先级。因此,如果正常的按钮单击和System.Windows.Forms.Timer事件通过SendMessage事件进行处理,并且BeginInvoke调用在消息队列中进行处理,我可以看到这是如何发生的


感谢所有的帮助和快速的建议!谁知道我花了多长时间才找到它

当你创建任何东西时,它可能是在主线程上创建句柄之前被后台线程访问的,或者它是在主线程以外的线程上创建的?你的意思是它会被执行,但有时会被延迟或丢失?@ScottChamberlain:我为该线程的每个公共/受保护成员添加了一个断点类,我可以看到它在显示之前仅由主线程实例化和访问。@SriramSakthivel:它始终被执行。它要么在调用BeginInvoke后立即执行,要么将被延迟到很长一段时间,直到调用控件上的另一个BeginInvoke。感谢您的快速回复!显示的提示是否为模式对话框?如果不是,DisplayPrompt方法是否会以某种方式跟踪当前是否显示提示,如果是,代码中是否可能存在错误?
11/13/2013 1:16:49 PM: Entering DisplayPrompt: BatchStateMachine
11/13/2013 1:16:49 PM: Before BeginInvoke of DisplayPrompt: BatchStateMachine
11/13/2013 1:16:49 PM: After BeginInvoke of DisplayPrompt: BatchStateMachine
The thread 0x998 has exited with code 0 (0x0).
The thread 0x1174 has exited with code 0 (0x0).
11/13/2013 1:27:01 PM: Entering ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: Before BeginInvoke of ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: After BeginInvoke of ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: Entering DisplayPrompt: 
11/13/2013 1:27:01 PM: Entering ClearPrompt: