AccessViolation 发生在 RichTextBox.ScrollToCaret 中 [英] AccessViolation occurs in RichTextBox.ScrollToCaret
问题描述
当非 UI 线程尝试将其输出附加到主线程中的 RichTextBox
UI 控件时,会发生难以跟踪的异常.
A hard to track exception is occuring when non-UI threads try to Append their output to RichTextBox
UI control in the Main Thread.
此异常随机发生,主要是当线程快速连续调用此方法时.它甚至发生在 2 个非 UI 线程中.
This exception occurs at random times, mostly when the threads are calling this method in quick succession. It occurs even in just 2 non-UI threads.
下面是 AppendLog 方法的代码.它位于主 UI 的 Form 类中.我生成了 2 个线程并将此方法作为 Action
Below is the code of AppendLog method. It is in the Main UI's Form class. I spawn 2 threads and pass them this method as Action<string> logDelegate
我什至有同步对象.
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:MyAppCodeChartingOfflineAnalyzer.cs:line 339
推荐答案
这种场景最简单的情况就是维护一个Queue
例如,如果您有消息列表.随意将值添加到队列中.在主窗体线程中,使用计时器组件并在提取值时锁定队列,例如锁(队列){rtbLog.AppendText(queue.Dequeue());}
.
The easiest situation in scenarios like this is to maintain a Queue<string> queue;
if you have a list of messages for example. Add values to to the queue at will. In the main form thread, use a timer component and lock the queue while pulling out values e.g. lock (queue) {rtbLog.AppendText(queue.Dequeue());}
.
这篇关于AccessViolation 发生在 RichTextBox.ScrollToCaret 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!