简体   繁体   English

System.InvalidOperationException:在执行CreateHandle()时无法调用Value Dispose()

[英]System.InvalidOperationException: Value Dispose() cannot be called while doing CreateHandle()

In my windows forms app clients sometimes report a strange exception: 在我的Windows窗体应用程序中,客户端有时会报告一个奇怪的异常:

System.InvalidOperationException: Value Dispose() cannot be called while doing CreateHandle()
   at System.Windows.Forms.Control.Dispose(Boolean disposing)
   at System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
   at System.ComponentModel.Component.Dispose()
   at MyCompany.SomeApp.DialogBox.Show(string caption, string message)
   at MyCompany.SomeApp.MainForm.Button1_Click(Object sender, MouseEventArgs e)

The code that causes this error looks like this: 导致此错误的代码如下所示:

namespace MyCompany.SomeApp
{
    public class DialogBox : CustomForm
    {
        public static DialogResult Show(string caption, string message)
        {
            using (DialogBox dialog = new DialogBox())
            {
                dialog.Text = caption;
                dialog.lblMessage.Text = message;
                return dialog.ShowDialog();
            }
        }
    }
 }

DialogBox is basically a class that inherits from Windows.Forms.Form and does some design changes, nothing special. DialogBox本质上是一个继承自Windows.Forms.Form的类,并且进行了一些设计更改,没有什么特别的。 The excepions happens at 异常发生在

return dialog.ShowDialog();

and not at the end of the using block as I would expect. 而不是像我期望的那样在using块的末尾。 It looks like somehow, within the ShowDialog() method and before the form's handle is created, the Dispose() method is called. 看起来好像是在ShowDialog()方法内,在创建窗体的句柄之前,调用了Dispose()方法。 But my DialogBox neither calls Dispose() itself nor swallows other exceptions, it only does some painting in the OnPaint() event. 但是我的DialogBox既不调用Dispose()本身也不吞咽其他异常,它仅在OnPaint()事件中进行一些绘制。

Does anybody have some clues how to get rid of this exception? 有人有一些线索可以摆脱这种例外吗?

Update: 更新:

Here is the only code in my CustomForm class (besides changes mode in the windows forms designer (added 2 Labels, a button and changed some colors) 这是我的CustomForm类中的唯一代码(除了Windows窗体设计器中的更改模式(添加了2个Label,一个按钮并更改了一些颜色)

Public Class CustomForm
    Inherits System.Windows.Forms.Form

    <DebuggerStepThrough()> _
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        Static pen1 As New Pen(Color.FromArgb(39, 46, 54), 21)
        Static pen2 As New Pen(Color.FromArgb(44, 51, 59), 1)
        Static pen3 As New Pen(Color.FromArgb(93, 99, 99), 1)
        Static pen4 As New Pen(Color.FromArgb(119, 124, 127), 1)
        Static pen5 As New Pen(Color.FromArgb(148, 157, 156), 1)
        Static pen6 As New Pen(Color.FromArgb(175, 185, 186), 1)

        With e.Graphics
            .DrawRectangle(Pens.Black, 0, 0, (Me.Width - 1), (Me.Height - 1))
            .DrawLine(pen1, 1, 11, Me.Width - 1, 11)
            .DrawLine(pen2, 1, 22, Me.Width - 2, 22)
            .DrawLine(pen3, 1, 23, Me.Width - 2, 23)
            .DrawLine(pen4, 1, 24, Me.Width - 2, 24)
            .DrawLine(pen5, 1, 25, Me.Width - 2, 25)
            .DrawLine(pen6, 1, 26, Me.Width - 2, 26)
        End With
    End Sub

    Private Const GWL_STYLE As Integer = (-16)
    Private Const WS_CAPTION As Integer = &HC00000
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
             (ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
    Public ReadOnly Property HasCaption() As Boolean
        Get
            return (GetWindowLong(Me.Handle, GWL_STYLE) And WS_CAPTION) = WS_CAPTION
        End Get
    End Property

End Class

Update: I changed the code a little bit because it was misleading. 更新:我更改了代码一点,因为它具有误导性。
In the stacktrace you can see that My.App.DialogBox.Show(...) is called. 在堆栈跟踪中,您可以看到My.App.DialogBox.Show(...)被调用。 Which is a static method that contains the using block. 这是一个静态方法,其中包含using块。
Neither DialogBox nore CustomForm override the ShowDialog() method of Form (which is why it is not shown in the stacktrace. DialogBox nore CustomForm都不会覆盖Form的ShowDialog()方法(这就是为什么它不显示在stacktrace中的原因)。

Think I found a clou here: http://softwareinvent.com/wordpress/?p=10 认为我在这里找到了一个中心: http ://softwareinvent.com/wordpress/?p =10

I kept getting an odd exception today: 我今天总是收到一个奇怪的例外:

Value Dispose() cannot be called while doing CreateHandle() 在执行CreateHandle()时不能调用Value Dispose()

I couldn't figure out what was causing it until I started commenting out large swaths of code (gotta love brute force debugging ). 在开始注释大量代码之前,我不知道是什么原因造成的(必须爱蛮力调试)。 It all came down to a very innocent looking line of code: 一切都归结为非常天真的代码行:

 if (Handle != IntPtr.Zero) 

This line of code grabs an unmanaged Windows handle. 这行代码将捕获非托管的Windows句柄。 As a result, that handle must be manually cleaned up 结果,必须手动清理该句柄

Looks exactly like my problem. 看起来完全像我的问题。 Maybe some weired threading issue in which, in rare conditions the HasCaption property is called exactly at the same time as the property HasCaption gets queried. 也许是一些奇怪的线程问题,在这种情况下,在极少数情况下,会在查询属性HasCaption的同时完全调用HasCaption属性。

Start by breaking it up, because now you can't tell if it's this using block or a Dispose inside the Dialog. 首先将其分解,因为现在您无法确定是在对话框中使用using块还是Dispose。

The following will be much more informative in the debugger: 以下内容将在调试器中提供更多信息:

using (DialogBox dialog = new DialogBox())
{
    dialog.Text = caption;
    var r = dialog.ShowDialog();
    return r;
}

Edit 编辑

I find this line in the error message 我在错误消息中找到了这一行

at My.App.DialogBox.Show() 在My.App.DialogBox.Show()

hard to reconcile with 难以调和

return dialog.ShowDialog();

So, is the error happening with .Show() or .ShowDialog() ? 那么,.Show()或.ShowDialog()是否发生错误?

I was also getting this exception off and on while running unit tests. 在运行单元测试时,我也断断续续地遇到了这种异常。 Turns out it was a threading issue. 原来这是一个线程问题。 Depending on timing, another thread was attempting to modify a GUI control while the main test thread was tearing down and disposing of the form that contained the control. 根据时序,另一个线程正试图修改GUI控件,而主测试线程正在拆除并处理包含该控件的表单。

I changed the unit test to wait for all expected GUI updates (even though that wasn't what was being tested) before exiting and the problem was resolved. 我更改了单元测试以等待所有预期的GUI更新(即使这不是正在测试的内容),然后退出并解决了问题。

This is quite old question. 这是一个很老的问题。 But if someone's interested in, this is my solution. 但是,如果有人对此感兴趣,这就是我的解决方案。


    `Timer tmr = new Timer();
    tmr.Interval = 1000;
    tmr.Tick += tmrTick;
    tmr.Start();
    void tmrTick(Object sender, EventArgs e){
        Timer tmr = sender as Timer;
        tmr.Stop();
        Form.Close(); //Form is form which wants to close by instance name. for example: this.Close()
    }`

Maybe there are some wrong syntax cause translating Vb to c# by myself. 也许是由于某些语法错误导致我自己将Vb转换为c#。 Sorry for this. 非常遗憾。 But it must be nearly like this by c#. 但是c#必须几乎像这样。

暂无
暂无

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

相关问题 使用Thread时,在执行CreateHandle()时出错,无法调用Value Dispose() - Value Dispose() cannot be called while doing CreateHandle() Error when Using Thread System.InvalidOperationException,同时检查空值 - System.InvalidOperationException while checking null value 在Firefox驱动程序中执行自动化测试时,WebDriver.dll中发生System.InvalidOperationException - System.InvalidOperationException occurred in WebDriver.dll while doing automation testing in Firefox driver 连接两个表时出现 System.InvalidOperationException - System.InvalidOperationException while join two table 无法连接到数据库,获取System.InvalidOperationException - Cannot connect to database, getting System.InvalidOperationException 运行RecognizeAsync时出现System.InvalidOperationException - System.InvalidOperationException while running RecognizeAsync 序列化时出现Web Service和System.InvalidOperationException - Web Service and System.InvalidOperationException while serializing $exception {在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。} System.InvalidOperationException - $exception {Invoke or BeginInvoke cannot be called on a control until the window handle has been created.} System.InvalidOperationException System.InvalidOperationException必须包含ViewModel的值 - System.InvalidOperationException must contain value for ViewModel System.InvalidOperationException:在调整自动填充列时无法执行此操作 - System.InvalidOperationException: This operation cannot be performed while an auto-filled column is being resized
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM