Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.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# 调用错误:尚未创建句柄_C#_.net_Vb.net_Winforms_Multithreading - Fatal编程技术网

C# 调用错误:尚未创建句柄

C# 调用错误:尚未创建句柄,c#,.net,vb.net,winforms,multithreading,C#,.net,Vb.net,Winforms,Multithreading,当某些表单中存在长时间运行的代码时(例如,在数据加载期间),我会在不同的线程上显示一个等待表单(说“请等待…”)。我显示如下形式: m_PopProcessingThread = New Thread(New ThreadStart( Sub() m_PopProcessingForm = New WaitingForm(m_Message) Application.Run(m_PopProcessingForm) End Sub)) m_

当某些表单中存在长时间运行的代码时(例如,在数据加载期间),我会在不同的线程上显示一个等待表单(说“请等待…”)。我显示如下形式:

m_PopProcessingThread = New Thread(New ThreadStart(
     Sub()
         m_PopProcessingForm = New WaitingForm(m_Message)
         Application.Run(m_PopProcessingForm)
     End Sub))
m_PopProcessingThread.Name = "Pop Processing Thread"
m_PopProcessingThread.SetApartmentState(ApartmentState.STA)
m_PopProcessingThread.Start()
While m_PopProcessingForm Is Nothing OrElse Not m_PopProcessingForm.IsHandleCreated
    Threading.Thread.Sleep(20) 'Wait a bit for the form to be created
End While
' Dispose of the pop processing form (by disposing of this form, thread is also exited)
m_PopProcessingForm.Invoke(Sub()
                               m_PopProcessingForm.Dispose()
                           End Sub)
然后我像这样把它藏起来:

m_PopProcessingThread = New Thread(New ThreadStart(
     Sub()
         m_PopProcessingForm = New WaitingForm(m_Message)
         Application.Run(m_PopProcessingForm)
     End Sub))
m_PopProcessingThread.Name = "Pop Processing Thread"
m_PopProcessingThread.SetApartmentState(ApartmentState.STA)
m_PopProcessingThread.Start()
While m_PopProcessingForm Is Nothing OrElse Not m_PopProcessingForm.IsHandleCreated
    Threading.Thread.Sleep(20) 'Wait a bit for the form to be created
End While
' Dispose of the pop processing form (by disposing of this form, thread is also exited)
m_PopProcessingForm.Invoke(Sub()
                               m_PopProcessingForm.Dispose()
                           End Sub)
这段代码非常有效,但我刚从一位客户那里收到一份错误报告:

Exception Type : 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)

堆栈跟踪指向我隐藏表单的代码部分。在
Invoke
调用之前,我循环直到所述句柄被创建,句柄怎么可能没有被创建?感谢您的帮助。

表单可能在您的IsHandleCreated检查之后,但在调用Dispose之前关闭。可能是用户单击了表单上的[x]或按了Ctrl-F4键。

使用后台工作和/或任务他们正是为此目的设计的。我知道这有点颠倒,通常任务应该在另一个线程中,而不是等待表单。但是考虑到当前代码在99999%的时间内有效,我宁愿修复它,也不愿更改我所有的代码。这将是令人惊讶的,这个表单上没有X按钮,并且表单不会长时间打开。我想这个错误可能是通过按Alt-F4发生的,但是,考虑到IsHandleCreated和Invoke指令相互遵循,表单将在这两个指令之间关闭,这将是非常令人惊讶的。您确实让我意识到,如果用户按Alt-F4,可能会有一个无限循环,所以谢谢您!因为调用被放置在消息队列上,所以在检查句柄之后,但在调用尝试调用之前,您可以很容易地获得一个Dispose。