System.InvalidOperationException: значение Dispose () не может быть вызвано при выполнении CreateHandle () - PullRequest
5 голосов
/ 22 сентября 2010

В моих приложениях windows 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)

Код, который вызывает эту ошибку, выглядит следующим образом:

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 в основном является классом, который наследуетиз Windows.Forms.Form и вносит некоторые изменения в дизайн, ничего особенного.Исключения происходят в

return dialog.ShowDialog();

, а не в конце блока using, как я ожидал.Так или иначе, в методе ShowDialog() и до создания дескриптора формы вызывается метод Dispose ().Но мой DialogBox не вызывает сам Dispose () и не глотает другие исключения, он только рисует некоторые события OnPaint ().

У кого-нибудь есть какие-то подсказки, как избавиться от этого исключения?

Обновление:

Вот единственный код в моем классе CustomForm (кроме режима изменений в конструкторе форм Windows (добавлено 2 ярлыка, кнопка и изменены некоторые цвета)

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

Обновление:Я немного изменил код, потому что он вводил в заблуждение.
В трассировке стека видно, что вызывается My.App.DialogBox.Show (...). Это статический метод, содержащий блок using.
Ни DialogBox, ни CustomForm не переопределяют метод ShowDialog () формы (именно поэтому он не отображается в трассировке стека.

Ответы [ 4 ]

3 голосов
/ 23 сентября 2010

Думаю, я нашел здесь гвоздь: http://softwareinvent.com/wordpress/?p=10

Сегодня я получал странное исключение:

Значение Dispose () не может быть вызвано, пока делает CreateHandle ()

Я не мог понять, что было причиной пока я не начал комментировать большой кусок кода (должен любить грубой принудительная отладка). Все сошло очень невинно выглядящей линии код:

if (Handle != IntPtr.Zero)

Эта строка кода захватывает неуправляемый Оконная ручка. В результате этого ручку необходимо почистить вручную

Выглядит точно так же, как моя проблема. Возможно, возникла проблема с потерей потоков, когда в редких случаях свойство HasCaption вызывается точно в то же время, когда запрашивается свойство HasCaption.

1 голос
/ 03 ноября 2011

Я также получал это исключение во время выполнения модульных тестов.Оказывается, это была проблема с потоками.В зависимости от времени другой поток пытался изменить элемент управления GUI, пока основной тестовый поток разрушал и удалял форму, содержащую элемент управления.

Я изменил модульный тест, чтобы дождаться всех ожидаемых обновлений GUI (хотя это было не то, что тестировалось) перед выходом и проблема была решена.

1 голос
/ 22 сентября 2010

Начните с того, что разбили его, потому что теперь вы не можете сказать, использует ли он блок или Dispose внутри диалога.

Следующее будет намного более информативным в отладчике:

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

Редактировать

Я нахожу эту строку в сообщении об ошибке

в My.App.DialogBox.Show ()

трудно смириться с

return dialog.ShowDialog();

Итак, происходит ли ошибка с .Show () или .ShowDialog ()?

0 голосов
/ 21 июня 2014

Это довольно старый вопрос.Но если кому-то интересно, это моё решение.


    `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()
    }`

Возможно, какой-то неправильный синтаксис вызывает перевод Vb в c # самостоятельноИзвини за это.Но это должно быть почти так с помощью c #.

...