2012-05-03 1 views
3

Исключительное отслеживание исключений происходит, когда потоки не-UI пытаются добавить свой вывод в UI-управление RichTextBox в главной теме.AccessViolation происходит в RichTextBox.ScrollToCaret

Это исключение происходит в случайные моменты времени, главным образом, когда потоки вызывают этот метод в быстрой последовательности. Это происходит даже в двух потоках, отличных от UI.

Ниже приведен код метода AppendLog. Он находится в классе формы основного интерфейса. Я создаю 2 потока и передаю им этот метод как Action<string> logDelegate

У меня даже есть syncobject на месте.

public void AppendLog(string message) 
    { 
     try 
     { 
      if (this.InvokeRequired) 
      { 
       this.Invoke(new Action<string>(this.AppendLog), message); 
      } 
      else 
      { 
       lock (_logSyncRoot) 
       { 

        if (rtbLog.TextLength > 100000) 
         rtbLog.ResetText(); 

        rtbLog.AppendText(message); 
        rtbLog.ScrollToCaret(); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      Logger.LogException(ex); 
     } 
    } 

System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.

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.DefWndProc(Message& m) 
at System.Windows.Forms.Control.WndProc(Message& m) 
at System.Windows.Forms.TextBoxBase.WndProc(Message& m) 
at System.Windows.Forms.RichTextBox.WndProc(Message& m) 
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
at System.Windows.Forms.Control.ControlNativeWindow.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 MyApp.UI.OfflineAnalyzer.AppendLog(String message) in D:\MyApp\Code\Charting\OfflineAnalyzer.cs:line 339 
+0

Попробуйте выполнить отладку с неуправляемой отладкой, чтобы увидеть непереработанный стек вызовов (нажмите правой кнопкой мыши на стек вызовов и нажмите символы загрузки, чтобы получить символы с серверов MS). –

+0

@Alois Трудно воспроизвести его по своему усмотрению. Я попробую то, что вы сказали. –

+0

InvokeRequired может привести к неправильным сортировочным окнам, когда вы записываете что-то, пока дескриптор окна формы еще не создан. У вас есть логические вызовы до того, как форма была видна? Если да, попробуйте удалить их, чтобы узнать, устраняет ли это вашу проблему. Отображается ли исключение в вашем основном потоке пользовательского интерфейса? Каковы были стеки вызовов других потоков? –

ответ

1

Самая простая ситуация в сценариях, как это поддерживать Queue<string> queue;, если у вас есть список сообщений, например. Добавьте значения в очередь по очереди. В потоке основной формы используйте компонент таймера и блокируйте очередь при вытягивании значений, например. lock (queue) {rtbLog.AppendText(queue.Dequeue());}.

+0

хорошо простой обходное решение. btw теперь только основной поток вызывает действительную операцию rtb, поэтому, вероятно, эта проблема не повторится. –

+0

Пробовал это. С помощью другого метода таймера, принадлежащего и управляемого основным потоком. с Q в общем. Еще проблема возникла во время вызова таймера, чтобы распечатать сообщения в Q. снова при доступе к элементу управления rtbLog. –

+0

Не могли бы вы отправить код? Обновление RTB с таймера не должно давать вам эту проблему вообще. –