首页 文章

AccessViolation发生在RichTextBox.ScrollToCaret中

提问于
浏览
3

当非UI线程尝试将其输出附加到主线程中的 RichTextBox UI控件时,会发生难以跟踪的异常 .

此异常在随机时间发生,主要是当线程快速连续调用此方法时 . 它甚至只出现在2个非UI线程中 .

下面是AppendLog方法的代码 . 它位于主UI的Form类中 . 我产生了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 : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

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

1 回答

  • 1

    像这样的场景中最简单的情况是,如果您有一个消息列表,那么维护一个 Queue<string> queue; . 随意将值添加到队列中 . 在主表单线程中,使用计时器组件并锁定队列,同时拉出值,例如 lock (queue) {rtbLog.AppendText(queue.Dequeue());} .

相关问题