Почему ошибка RaceOnRCWCleanup при закрытии формы с помощью элемента управления WebBrowser?

VS2008,.NET 2, VB.NET, XP...

У меня есть форма Windows с элементом управления WebBrowser и кнопкой Close, которая просто выполняет Me.Close. Кнопка отмены формы установлена ​​на кнопку "Закрыть", чтобы я мог нажать ESC, чтобы закрыть форму.

Я устанавливаю свойство DocumentText элемента управления WebBrowser в событии загрузки, и отображается HTML.

Запуск приложения из Visual Studio, если я нажму кнопку Close, форма закрывается без ошибок.

Если я нажму кнопку ESC, я получу

обнаружен RaceOnRCWCleanup Сообщение: Была сделана попытка бесплатно RCW, который используется. RCW используется в активной нити или другой поток. Попытка освободить использование RCW может привести к повреждению или потери данных.

Если я запустил приложение вне VS, я не получу ошибки.

Любые идеи а) почему ошибка и б) как предотвратить или подавить ее?

Большое спасибо заранее.

1 ответ

Это не ошибка, это предупреждение. Создано управляемым помощником по отладке (MDA), расширением отладчика для управляемого кода, который считает, что в вашем коде что-то не так. Обувь подходит. Вы используете RCW, WebBrowser - это элемент управления COM. Вы убиваете RCW, вы закрываете форму. MDA работает, потому что думает, что видит используемый веб-браузер и его убивают до того, как запрос будет завершен. Это обычно имеет смысл, если вы используете поток в своем коде.

Вы? Если нет, не теряйте сна над ним. COM использует подсчет ссылок, печально известный тем, что не может разрешать циклические ссылки.

Хорошо, я получил для этого репродуцирование, включенный комментариями. Да, это вызвано свойством CancelButton формы или с помощью свойства DialogResult. Это происходит, когда WB имеет фокус, он видит клавишу Escape. Часть водопроводной сети ActiveX предназначена для того, чтобы сообщить об этом контейнеру, чтобы он мог реагировать на нажатия клавиш, которые должны иметь побочный эффект. Быстрые нажатия клавиш, Tab, Enter. И побег. Если кнопка затем закрывает форму, отладчик видит, что WB расположен, когда в стеке есть активные стеки кадров из кода RCW. Опасность состоит в том, что это может привести к сбою, когда вызываемый код возвращается с момента выпуска COM-компонента, это не редкость.

Увидеть этот крах довольно маловероятно, но я могу себе представить, что это могло бы бомбить, когда поток финализатора запускается непосредственно перед нажатием кнопки Click event. Обходной путь для MDA и потенциальный сбой - это задержка закрытия формы до тех пор, пока код ActiveX не будет запущен. Элегантно сделано с Control.BeginInvoke(). Вот так:

private void CancelButton_Click(object sender, EventArgs e) {
 this.BeginInvoke((MethodInvoker)delegate { this.Close(); });
 }

licensed under cc by-sa 3.0 with attribution.