Это приложение имеет веб-службу WCF, вызываемую приложением WinForms. Приложение WinForms имеет класс WCFCache
для управления данными из службы. В этом классе есть такой раздел, чтобы управлять необязательным настраиваемым разделом конфигурации, который имеет подмножество машин:
private bool? m_HasCustomConfiguration = null;
public bool HasCustomConfiguration
{
get
{
if (m_HasCustomConfiguration == null)
m_HasCustomConfiguration = (CustomConfiguration != null);
return (bool)m_HasCustomConfiguration;
}
}
private WCFService.CustomConfiguration m_CustomConfiguration = null;
public WCFService.CustomConfiguration CustomConfiguration
{
get
{
if (m_CustomConfiguration == null)
{
if (m_HasCustomConfiguration.HasValue
&& !m_HasCustomConfiguration.Value)
return null;
try
{
using (WCFService.WCFServiceClient wcf = new WCFService.WCFServiceClient())
{
m_CustomConfiguration =
wcf.GetCustomConfiguration(Machine.ProcessID);
// Above method returns null if no record exists.
m_HasCustomConfiguration = (m_CustomConfiguration != null);
}
} catch (Exception e) {
// Error logging & re-throw
}
}
return m_CustomConfiguration;
}
}
Когда я перехожу через отладчик в код, который вызывает любое из указанных выше свойств, например:
if (!Program.WCFCache.HasCustomConfiguration)
return new List<CustomComponents>();
... это вызывает следующее исключение:
System.AccessViolationException was unhandled
Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Source="System.Windows.Forms"
...
Когда я перехожу на строку, содержащую ссылку, появляется длинная пауза, за которой следует всплывающее окно VS с исключением.
Исключение не появляется, когда я просто ставил точку останова после выполнения вышеуказанного кода. Он даже не появляется, когда я помещаю точку останова внутри аксессуаров свойств. Это происходит только тогда, когда я перехожу на линию с одним из этих свойств снаружи. (Итак, есть обходной путь, но это может быть боль.)
Почему это происходит? Могу ли я остановить его?
Изменить: все приложение было написано в прошлом году в версии 3.5 С#/.NET с WCF, взаимодействующей между компонентами; то есть у нас нет устаревших неуправляемых DLL. Только два неуправляемых вызова: один для advapi32.dll, когда приложение WinForms загружается, в процедуре определения имени пользователя. Проблема, с которой я столкнулась, происходит только в этом одном месте в коде, в месте, которое примерно так же не связано с секцией входа, как вы можете получить. Другой - для kernel32.dll, в силовом сжатии GC, после того, как все сделано с результатами вызовов, подобных приведенным выше.
В конце концов я обнаружил, что другие столкнулись с этой ситуацией и что это, скорее всего, ошибка Visual Studio. Я использовал VS 2008, когда возникла проблема.
Используете ли вы какой-либо P/Invoke или другой такой собственный код? Вероятность того, что вы должны начать искать.
Это исключение является симптомом более серьезной проблемы, а именно повреждения памяти (что, в конце концов, говорит об исключении). Если это было родное приложение, вы получили бы сбой.
Итак, посмотрите на какие-либо собственные вызовы, убедитесь, что они работают правильно, возможно, запустите их под отладчиком, чтобы попытаться уловить ошибку ближе к дому.
Извините, не могу дать лучший совет, учитывая обстоятельства.
unsafe
код? Или какие-нибудь сторонние библиотеки? Честно говоря, чистый код CLR никогда не должен вызывать AccessViolationException
при отсутствии аппаратного сбоя. Либо где-то есть какой-то глючный нативный код, ваш процессор перегорел (что было бы указано другими программами, аварийно завершающими работу), либо вы обнаружили ранее непроверенный угловой случай ... В чем я сомневаюсь ...
HasCustomConfiguration
? Имя члена предполагает, что оно должно бытьtrue
когдаCustomConfiguration != null
, но логика обратная.