2012-06-25 2 views
1

У меня есть группа фоновых событий.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); 
    } 
} 
+0

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

+0

Ну, эта блокировка была чистой догадкой в ​​моей части ... – mamcx

+1

Общее правило: * никогда * не блокировать реальный объект (например, 'this'). Всегда используйте элемент 'new object()' только для блокировки. См. [Почему Великая Идея не так велика] (http://msdn.microsoft.com/en-us/magazine/cc188793.aspx#S7) –

ответ

1

Это может произойти, если ведение журнала запускается очень быстро (до создания дескриптора формы). Перед вызовом каких-либо методов в элементе управления проверьте значение editLog.IsHandleCreated == true. Это может помочь, в противном случае используйте поточно-безопасный Queue<string> (окруженный оператором lock (obj) {}) и поместите таймер в вашу форму, чтобы периодически читать эту очередь для новых журналов.

+0

Я реализую обе и по-прежнему получаю ту же проблему. – mamcx

+0

Добавьте дополнение для редактирования editLog.IsHandleCreated == true перед добавлением текста. – Mangist

+0

По-прежнему та же проблема. Даже GUI заморозить :( – mamcx

0

Ну, наконец, проблема. Удаление этого устранить проблему (и работать с нормальным BeginInvoke, без трюков, замков и):

editLog.SelectionStart = editLog.TextLength; 
editLog.ScrollToCaret(); 

я попробовать использовать http://nlog-project.org/ и моя первая работа attemp completelly нормально (с http://nlog-project.org/wiki/RichTextBox_target). Когда я установил autoScroll="true", повторите ту же ошибку. Вот как я нахожу эту проблему.

Смежные вопросы

 Смежные вопросы