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.
此异常在随机时间发生,主要是当线程快速连续调用此方法时。即使在仅两个非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方法的代码。它在主界面的Form类中。我产生了2个线程,并通过 Action< string> logDelegate
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:\MyApp\Code\Charting\OfflineAnalyzer.cs:line 339
推荐答案
在这种情况下,最简单的情况是维持 Queue< string>队列;
,例如,如果有消息列表。随意将值添加到队列中。在主表单线程中,使用计时器组件并在拉出值(例如锁(队列){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屋!