频繁写richTextBox1,暴内存错误(c#代码)

waterwan 2015-06-29 09:43:01
一个程序中有两个线程,一个线程往listSearchLines中每1秒加入文字,ProcessDataThread 线程读出listSearchLines 中的文字,显示在主界面UI的richTextBox1对象中,运行一段时间,就会出现richTextBox 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

请问我的问题错在哪里?

Thread ProcessDataThread = new Thread((ThreadStart)ProcessData);
ProcessDataThread.IsBackground = true;
ProcessDataThread.Start();

private static List<string> listSearchLines = new List<string>();

private void ProcessData()
{
while (true)
{
try
{
StringBuilder tsb = new StringBuilder();

string[] temp = null;
lock (listSearchLines)
{
temp = listSearchLines.ToArray();
listSearchLines.Clear();
}

if (temp.Length == 0)
{
Thread.Sleep(10);
continue;
}

foreach (string s in temp)
{
tsb.AppendLine(s);
}

this.Invoke((EventHandler)delegate
{
if (richTextBox1.Text.Length > 5000)
{
richTextBox1.Clear();
}
richTextBox1.AppendText(tsb.ToString());
richTextBox1.Focus();
richTextBox1.Select(richTextBox1.Text.Length, 0);
richTextBox1.ScrollToCaret();
richTextBox1.HideSelection = true;

});
tsb.Clear();

}
catch
{

}
}
}
...全文
717 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
threenewbee 2015-06-30
  • 打赏
  • 举报
回复
根本性地错误,在线程中操作控件,应该用invoke传委托。
exception92 2015-06-30
  • 打赏
  • 举报
回复
最坑爹的 就是用 while (true) 类似死循环的读取方式,代码设计不好 就容易一直while 下去,搞的把你的内存给消耗完。 使用thread 显示,不清楚要求的显示 速率得多快??不如搞个timer,每隔1s 读取一次。 不如把写入的 字符 存入队列,使用排队,出队方式 显示字符。
waterwan 2015-06-30
  • 打赏
  • 举报
回复
我把两个线程单独提取成一个新程序,测试又没有发现问题了,估计是我程序中其他地方有问题。
caoqinghua 2015-06-30
  • 打赏
  • 举报
回复
在线程中操作richTextBox ,用委托.
waterwan 2015-06-30
  • 打赏
  • 举报
回复
我的QQ号:228353218,有知道我错在哪里的朋友,加我Q,告诉我一下,我帮您充手机费。呵呵。
waterwan 2015-06-30
  • 打赏
  • 举报
回复
你考虑下: 1。你这里的this是什么,它凭什么去操作richTextBox1的内容 回复这里的THIS,是代表界面主线程。 2。这里tsb的作用域是多大[/quote] tsb的作用域就在这个显示的子线程中吧。 private void ProcessData() { while (true) { try { StringBuilder tsb = new StringBuilder();
Poopaye 2015-06-30
  • 打赏
  • 举报
回复
引用 3 楼 waterwan 的回复:
[quote=引用 1 楼 caozhy 的回复:] 根本性地错误,在线程中操作控件,应该用invoke传委托。
版主:这段代码是用invoke传委托吧?这样写不行吗? this.Invoke((EventHandler)delegate { if (richTextBox1.Text.Length > 5000) { richTextBox1.Clear(); } richTextBox1.AppendText(tsb.ToString()); richTextBox1.Focus(); richTextBox1.Select(richTextBox1.Text.Length, 0); richTextBox1.ScrollToCaret(); richTextBox1.HideSelection = true; }); [/quote] 你考虑下: 1。你这里的this是什么,它凭什么去操作richTextBox1的内容 2。这里tsb的作用域是多大
waterwan 2015-06-30
  • 打赏
  • 举报
回复
补允一下,如果调到1分钟插入一次,测2个小时都没事,如果调用1秒钟插入一次,几分钟就会报错。
waterwan 2015-06-30
  • 打赏
  • 举报
回复
引用 2 楼 duanzi_peng 的回复:
最坑爹的 就是用 while (true) 类似死循环的读取方式,代码设计不好 就容易一直while 下去,搞的把你的内存给消耗完。 使用thread 显示,不清楚要求的显示 速率得多快??不如搞个timer,每隔1s 读取一次。 不如把写入的 字符 存入队列,使用排队,出队方式 显示字符。
显示速率是由插入线程决定的,我爆力测试是1秒钟插入一条,然后显示线程是发现有文字,就马上显示,如果没有就休息10豪秒。再判断有没有新文字。这样一直循环下去。
waterwan 2015-06-30
  • 打赏
  • 举报
回复
引用 1 楼 caozhy 的回复:
根本性地错误,在线程中操作控件,应该用invoke传委托。
版主:这段代码是用invoke传委托吧?这样写不行吗? this.Invoke((EventHandler)delegate { if (richTextBox1.Text.Length > 5000) { richTextBox1.Clear(); } richTextBox1.AppendText(tsb.ToString()); richTextBox1.Focus(); richTextBox1.Select(richTextBox1.Text.Length, 0); richTextBox1.ScrollToCaret(); richTextBox1.HideSelection = true; });

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧