gpt4 book ai didi

c# - XNA 游戏启动的表单中带有 RichTextBox.ScrollToCaret 的 AccessViolationException

转载 作者:太空宇宙 更新时间:2023-11-03 11:11:06 24 4
gpt4 key购买 nike

我在 RichTextBox.ScrollToCaret 方面遇到了一个有点令人沮丧的障碍。我有将消息打印到 RichTextBox 的代码。当每条消息发送到表单时,它被分成多行并格式化,然后连接每一行并将结果发送到 RichTextBox.Append。然后,进行以下两个调用以滚动到框的底部:

outputBox.Select(outputBox.Text.Length, 0);
outputBox.ScrollToCaret();

当打印一条消息时,没问题。打印少量消息时,没有问题。当快速连续打印一堆消息时,它会随机(在它发生之前打印多少消息)抛出 AccessViolationException(“试图读取或写入 protected 内存。这通常表明其他内存已损坏。”,完整详细信息 here ) 下次调用 Append 时 在该框上添加下一条消息。这在快速连续执行时发生,在每次使用 RichTextBox.ScrollToCaret 时发生。我使用的以下代码工作正常:

outputBox.Focus();
outputBox.Select(outputBox.Text.Length, 0);

我也发现,即使我捕捉到异常并将其丢弃,程序也会在下次调用 Append 时挂起。所以,我认为这是 RichTextBox 中实际代码的问题。有人有什么想法吗?

如果有人需要,我可以发布更多我的代码,但情况真的很简单。需要注意的几件事是没有多线程(除了固有的 UI 线程),因此发送消息的对象和接收消息的表单在同一个线程上。此外,这是在 .NET 4.0 下。

我发现另一个问题解决了这个问题,但只提供了一个解决方法,没有真正的解释:AccessViolation occurs in RichTextBox.ScrollToCaret .不幸的是,我在线程方面的经验不是我想要的,所以我无法让他们的解决方案正常工作,但幸运的是,我在上面发布的内容工作得很好。

更新1

所以它看起来像是与 XNA 有关的一些测试,所以这可能是我对它如何与线程一起工作的误解。我一直无法在纯 WinForms 应用程序中重现错误,但可以通过简单的 XNA 游戏轻松完成。我把两个都压缩在这里供你查看。为错误道歉。 https://dl.dropbox.com/u/16985121/StackOverFlowExamples.zip

最佳答案

我有同样的问题。我的情况略有不同,但问题基本相同。我混淆了 C++/CLI 和 C# 形式的代码。

C++/CLI 中的一个线程调用 C# 形式的函数以将消息打印到 richtextbox。

“慢慢地”调用这个函数是可以的。但是如果调用函数发生得非常快并且经常发生,程序就会随机崩溃。

这是我的代码。

void PrintOutLog(System::String^ s)
{
Monitor::Enter(this->richTextBox_LogBox);
try
{
if(this->richTextBox_LogBox->InvokeRequired)
{

AddListItem^ d = gcnew AddListItem(this, &PrintOutLog);
array<Object^>^ myStringArray = {s};
this->richTextBox_LogBox->BeginInvoke(d, myStringArray);
}
else
{
this->richTextBox_LogBox->AppendText(s + "\n");
this->richTextBox_LogBox->SelectionStart = this->richTextBox_LogBox->Text->Length;
this->richTextBox_LogBox->ScrollToCaret();
}

}
finally
{
Monitor::Exit(this->richTextBox_LogBox);
}

}

事实证明,如果我注释掉以下两行代码,程序不会再因内存访问冲突而崩溃。

this->richTextBox_LogBox->SelectionStart = this->richTextBox_LogBox->Text->Length;
this->richTextBox_LogBox->ScrollToCaret();

如果我注释掉这两行,那么当 C# 窗体没有焦点时,richtextbox 不会在文本框的末尾显示新的日志消息。

我可以使用您的解决方案,该解决方案在放置文本之前获得焦点,但如果我这样做,它始终位于我需要保持在最顶部的其他窗口之上。所以我不能那样做。

我查阅了 MSDN 页面 http://msdn.microsoft.com/en-us/library/system.windows.forms.textboxbase.scrolltocaret.aspx并在页面中间找到了这个。

如果控件没有焦点或插入符号已位于控件的可见区域,则此方法无效。

但我相信这不是真的。似乎当焦点不在 richtextbox 控件上时调用 ScrollToCaret() 时,我可以看到 richtextbox 的滚动条在收到新消息时向下移动,这意味着它打印消息并更新即使它没有焦点。

我试图锁定 richtextbox 以防止多线程,但它没有解决访问冲突问题。如果除了使用 focus() 函数之外还有其他解决方案来解决此问题,那就太好了。

谢谢。

关于c# - XNA 游戏启动的表单中带有 RichTextBox.ScrollToCaret 的 AccessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14027505/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com