Когда зарегистрировать метод, который будет вызывать Form.Invoke для события? - PullRequest
4 голосов
/ 12 апреля 2011

Я получаю следующее исключение в приложении Windows Form

System.InvalidOperationException: Invoke или BeginInvoke нельзя вызывать для элемента управления, пока не создан дескриптор окна.

Метод, в котором возникает исключение, вызывает this.Invoke (System.Windows.Forms.Form.Invoke).Этот метод зарегистрирован в событии другого класса в конструкторе, что, кажется, приводит к состоянию гонки и этому исключению.

public Form1()
{
    InitializeComponent();
    SomeOtherClass.Instance.MyEvent += new SomeDelegate(MyMethod);
}

private void MyMethod()
{
    this.Invoke((MethodInvoker)delegate
    {
        // ... some code ...
    }
}

На каком этапе жизненного цикла формы создается дескриптор?В каком случае формы будет безопасно зарегистрировать метод для иностранного события?

Ответы [ 4 ]

2 голосов
/ 12 апреля 2011

Хорошо, теперь я изменил это на:

public Form1(){
    InitializeComponent();
}
protected override void OnHandleCreated(EventArgs e)
{
    base.OnHandleCreated(e);
    SomeOtherClass.Instance.MyEvent += new SomeDelegate(MyMethod);
}
private void MyMethod()
{
    this.Invoke((MethodInvoker)delegate
    {
        // ... some code ...
    }
}

альтернативная версия будет

public Form1(){
    InitializeComponent();
    SomeOtherClass.Instance.MyEvent += new SomeDelegate(MyMethod);
}
private void MyMethod()
{
    if (this.IsHandleCreated)
    {
        this.Invoke((MethodInvoker)delegate
        {
            // ... some code ...
        }
    }
}
2 голосов
/ 12 апреля 2011

Отмените обратный вызов InitializeComponent (), прежде чем зарегистрировать обработчик, как предложено по битам

Вы получите ту же проблему, когда форма будет размещена, поэтому обработчик повторно не обрабатывает.

Вы можете сделать что-то вроде if(this.IsHandleCreated) в своем обработчике, чтобы быть в безопасности.

2 голосов
/ 12 апреля 2011

Я думаю, что если вы зарегистрируете метод в событии OnShow, вы должны быть в безопасности.

0 голосов
/ 12 апреля 2011

Как уже упоминалось, IsHandleCreated - это путь. Следующий фрагмент рассказывает, как это сделать.

public class TestEvent : Form
{

    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        MyMethod();

    }
    private void MyMethod()
    {

        this.Invoke(new Action(() =>
                                   {
                                      //Here goes your code.
                                   }));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...