简体   繁体   English

调用或BeginInvoke不能称为错误

[英]Invoke or BeginInvoke cannot be called Error

I have a program that is used by Clients world wide. 我有一个可供全球客户使用的程序。 I check my error logs and quite a few seem to be having an exception (listed below) thrown that I can't really figure out or trace. 我检查了我的错误日志,似乎有很多异常(下面列出)被抛出,我无法真正找出或跟踪。

I have some invokes but they are all protected by InvokeRequired. 我有一些调用,但是它们都受InvokeRequired保护。 Now I'm thinking, if i should use use the if (HandleCreated) instead. 现在我在想,如果我应该使用if(HandleCreated)代替。

I am not even sure where or when the exception is thrown. 我什至不知道在哪里或何时引发异常。

In start up, after the InitializeComponent();, I have some tasks that require access to some controls such as datagridview. 在启动过程中,在InitializeComponent();之后,我有一些任务需要访问某些控件,例如datagridview。 However, Like I said, I try to protect them with InvokeRequired. 但是,就像我说的,我尝试使用InvokeRequired保护它们。 I am not sure if that's the place causing the problem. 我不确定是不是引起问题的地方。

What are the suggestions I could perform so try and trace this problem? 我可以执行哪些建议,以便尝试查找此问题?

Anyway, this is my exception: 无论如何,这是我的例外:

    System.InvalidOperationException: Invoke or BeginInvoke cannot be called on a 

control until the window handle has been created.
   at System.Windows.Forms.Control.WaitForWaitHandle(WaitHandle waitHandle)
   at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate 

method, Object[] args, Boolean synchronous)
   at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
   at System.Windows.Forms.Control.Invoke(Delegate method)
   at ..()
   at ..()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, 

ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

No, that cannot happen if you use InvokeRequired. 不,如果使用InvokeRequired,则不会发生这种情况。 It will only be true when the Handle is valid. 仅当句柄有效时,它才为真。 Very simple avoid to anyway, just don't subscribe the event or start the thread until the Load event fires. 无论如何,都非常简单地避免,只是不要订阅事件或在Load事件触发之前启动线程。

This crash occurs when the form closes . 表单关闭时会发生此崩溃。 Something you cannot see in the stack trace because that happens on another thread. 您无法在堆栈跟踪中看到的东西,因为那发生在另一个线程上。 There's a race condition in InvokeRequired + Begin/Invoke(). InvokeRequired + Begin / Invoke()中存在竞争条件。 InvokeRequired might return true and a microsecond later the form closes. InvokeRequired可能会返回true,并在一毫秒后关闭表单。 Your Begin/Invoke call will fail with this exception. 您的Begin / Invoke调用将因此异常而失败。

This is not a race you can solve. 这不是您可以解决的比赛。 You must ensure that the thread can no longer call BeginInvoke() before allowing the form to close. 必须确保在关闭窗体之前,线程不能再调用BeginInvoke()。 Which invariably means you have to prevent the form from closing. 这总是意味着您必须防止表单关闭。 Background info is in this answer . 本答复中包含背景信息。

I'm not sure if trace would totally help you here. 我不确定跟踪是否可以完全帮助您。 It's obvious somewhere in you code you are calling invoke/BeginInvoke before the handle has been created. 很明显,在创建句柄之前,您正在调用代码的地方调用invoke / BeginInvoke。 Now, what I'm suggesting may require some work but you'll nail the caller that is prematurely invoking a non-created handle. 现在,我建议的内容可能需要一些工作,但是您会发现正在过早调用未创建的句柄的调用者。 I used this technique when trying to trace a lock/unlock threading issue in some old C++ legacy code in production. 当尝试在生产中的某些旧C ++旧代码中跟踪锁定/解锁线程问题时,我使用了此技术。 It worked so well, I just left it as is. 它运行得非常好,我照原样保留了它。

Here's my technique. 这是我的技术。 Create an Extension class that accepts objects that support Invoke/BeginInvoke and EndInvoke. 创建一个扩展类,该类接受支持Invoke / BeginInvoke和EndInvoke的对象。 It may look something like this: 它可能看起来像这样:

public static class MyInvokeExtension
{
   public static void TempInvoke(this objectthatsupportsinvoke, ...)
   {
        try
        {
           objectthatsupportsinvoke.Invoke(...);
        }
        catch(Exception ex)
        {
           Console.WriteLine();  // put a break-point here
        }
   }

   // add other BeginInvoke and EndInvoke methods and do the same as above.
}
  • Now do a search and replace throughout your code and replace all Invoke like calls with TempInvoke like calls. 现在搜索并替换整个代码,并将所有类似Invoke的调用替换为类似TempInvoke的调用。
  • Run you application in debug. 在调试中运行您的应用程序。
  • At some point you will hit a break point. 在某个时候,您会遇到一个断点。
  • Use the call-stack window to find who is calling your invoke method earlier than they should. 使用调用堆栈窗口可以查找谁比他们更早调用了invoke方法。

I know this is a lot of work but its worth it in the long run, trust me. 我知道这是很多工作,但从长远来看值得,相信我。 In fact, you can even use this code to validate that the object can handle invokes at a given point in time. 实际上,您甚至可以使用此代码来验证对象可以在给定的时间点处理调用。

Let me know how it goes. 让我知道事情的后续。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我从不使用 Invoke 或 BeginInvoke 时,无法调用 Invoke 或 BeginInvoke 错误 - Invoke or BeginInvoke cannot be called Error when I never use Invoke or BeginInvoke “在标签上”之前,无法在控件上调用“调用”或“BeginInvoke” - “Invoke or BeginInvoke cannot be called on a control until” on a Label C#编译错误:“在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke。” - C# compile error: “Invoke or BeginInvoke cannot be called on a control until the window handle has been created.” 错误:在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke - Error: Invoke or BeginInvoke cannot be called on a control until the window handle has been created 无法在控件上调用Invoke或BeginInvoke…即使使用CreateControl() - Invoke or BeginInvoke cannot be called on a control… even using CreateControl() 无法在尚未创建的控件上调用Invoke或begininvoke - Invoke or begininvoke cannot be called on a control which is not yet created dataGridView_CellContentClick:不能在控件上调用Invoke或BeginInvoke - dataGridView_CellContentClick: Invoke or BeginInvoke cannot be called on a control 调用了“ Invoke”和“ BeginInvoke”,但从未解决 - 'Invoke' and 'BeginInvoke' are called but never resolved 无法在控件上调用BeginInvoke - BeginInvoke cannot be called on a control $exception {在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。} System.InvalidOperationException - $exception {Invoke or BeginInvoke cannot be called on a control until the window handle has been created.} System.InvalidOperationException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM