У меня есть группа фоновых событий.Winforms: Попытка чтения или записи защищенной памяти. Это часто свидетельствует о том, что другая память повреждена
Все они называют бревно:
private void log(string text, params object[] values)
{
if (editLog.InvokeRequired)
{
editLog.BeginInvoke(
(MethodInvoker)delegate
{
this.log(text, values);
});
}
else
{
text = string.Format(text, values) + Environment.NewLine;
lock (editLog)
{
editLog.AppendText(text);
editLog.SelectionStart = editLog.TextLength;
editLog.ScrollToCaret();
}
}
}
Иногда я получаю это, но иногда нет:
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
StackTrace:
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.RichTextBox.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Object& editOle)
at System.Windows.Forms.TextBoxBase.ScrollToCaret()
at Program1.frmMain.log(String text, Object[] values) in
...
...
...
PD: Не всегда останавливаются на этой линии, случайным образом будет один из три раза используются методы/свойства editLog. Не всегда исключение - это бросок. Иногда выглядят как замораживание вещей. Но не основной пользовательский интерфейс, просто поток сообщений (то есть: журнал выглядит как никогда не звонит снова)
Приложение представляет собой единую форму с фоновым процессом. Я не могу понять, что я делаю неправильно с этим ...
UPDATE:
я делаю предложение Mangist, это код (огонь таймер на 100мс). Тот же результат:
private Queue<String> logs = new Queue<String>();
private void timerLog_Tick(object sender, EventArgs e)
{
lock (logs)
{
for (int i = 0; i < logs.Count; i++)
{
editLog.AppendText(logs.Dequeue());
editLog.SelectionStart = editLog.TextLength;
editLog.ScrollToCaret();
}
}
}
private void log(string text, params object[] values)
{
text = string.Format(text, values) + Environment.NewLine;
if (editLog.InvokeRequired)
{
editLog.BeginInvoke(
(MethodInvoker)delegate
{
lock (logs)
{
logs.Enqueue(text);
}
//this.log(text, values);
});
}
else
{
logs.Enqueue(text);
}
}
Какова цель блокировки элемента управления в потоке пользовательского интерфейса? Вы уже гарантировали однопоточный доступ с помощью насоса сообщений. –
Ну, эта блокировка была чистой догадкой в моей части ... – mamcx
Общее правило: * никогда * не блокировать реальный объект (например, 'this'). Всегда используйте элемент 'new object()' только для блокировки. См. [Почему Великая Идея не так велика] (http://msdn.microsoft.com/en-us/magazine/cc188793.aspx#S7) –