BeginInvoke завершается ошибкой, потому что дескриптор окна не был создан - PullRequest
1 голос
/ 16 марта 2012

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

  1. Открыть форму поиска клиента
  2. Просмотр случайных клиентов Информация в форме информации о клиентах
  3. откройте форму crm, и она автоматически покажет клиента A. Затем добавьте к нему файл с помощью draganddrop.
  4. Закройте последние две формы, выберите случайного клиента B и сделайте то же самое.
  5. Закройте последние две формы, выберите клиента A и добавьте новый файл. Ошибка !!!

Вот код, который не работает:

private void FireFileCountChanged() {
    if (FileCountChanged != null)
        BeginInvoke(new DeferEvent(FireFileCountChangedDeferred), 2); // FAILS

"Произошло необработанное исключение типа« System.InvalidOperationException »в System.Windows.Forms.dll

Дополнительная информация: Invoke или BeginInvoke не могут быть вызваны для элемента управления, пока не будет создан дескриптор окна. "

Я попытался добавить следующее:

private void FireFileCountChanged() {
        if (FileCountChanged != null && this.Handle != null) // CHANGED AND FAILS.
            BeginInvoke(new DeferEvent(FireFileCountChangedDeferred), 2);
    }

Но this.handle дает:

this.Handle выдал исключение типа System.ObjectDisposedException и "Невозможно получить доступ к удаленному объекту. \ R \ nИмя объекта: 'AttachmentsControl'."

Затем я добавил тайм-аут в 10 секунд в качестве первой строки метода, но дескриптор все еще не создан. Была ли ручка каким-то образом расположена, когда одно из окон было закрыто? И что с этим можно сделать? Любая помощь приветствуется. Я немного застрял.

private void FireFileCountChangedDeferred(int repostCount) {
    if (FileCountChanged != null) {
        if (repostCount > 0) {
            //black magic is somehow involved in getting this event to fire *after* the filewatcher reports the change.
            System.Threading.Thread.Sleep(10);
            BeginInvoke(new DeferEvent(FireFileCountChangedDeferred), repostCount - 1);
        } else
            FileCountChanged(this, null);
    }
}

private void CopyFiles(string[] files, bool reload) {
    if (CreatePath()) {
        foreach (string src in files) {
            try {
                string dest = MakeSafeFilename(src);
                File.Copy(src, dest);
                FireFileCountChanged();
            } catch (Exception ex) {
                //Util.Print("Copy ex: {0}", ex.Message);
                ErrMsg("Error while copying:{1}{0}", ex.Message, environment.NewLine);
            }
        }
    }
}

private void Lstv_DragDrop(object sender, DragEventArgs ea) {
    if (m_CanAdd) {
        string[] files = GetDraggedFiles(ea);
        if (files != null)
            CopyFiles(files, true);
        else if (OutlookDataObject.HoldsOutlookData(ea) && CreatePath()) {
            try {
                OutlookDataObject.CopyDroppedFiles(ea, m_Path, OutlookFilenameCallback);
            } catch (Exception ex) {
                //Util.Print("Copy ex: {0}", ex.Message);
                ErrMsg("Error copying from Outlook:{1}{0}", ex.Message, Environment.NewLine);
            }
        }
    }
}

Решение

private void FireFileCountChanged() {
                while (!this.IsHandleCreated) // added
                          System.Threading.Thread.Sleep(100); //added

    if (FileCountChanged != null)
        BeginInvoke(new DeferEvent(FireFileCountChangedDeferred), 2);

1 Ответ

7 голосов
/ 16 марта 2012

Вам необходимо проверить свойство IsHandleCreated , а не сравнивать дескриптор со значением NULL. Чтение свойства Handle считается самой операцией пользовательского интерфейса.

private void FireFileCountChanged() {
    if (FileCountChanged != null && this.IsHandleCreated)
        BeginInvoke(new DeferEvent(FireFileCountChangedDeferred), 2);
}

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

...