1

我在 GTK textview 中发现了奇怪的异常,希望有人能解释一下。

有一个简单的功能可以滚动到窗口底部:

richTextBox.ScrollToIter(richTextBox.Buffer.EndIter, 0, true, 0, 0);

在大多数情况下,这可能应该有效。但有时它会使用 MemoryAccessViolation(Linux 中的 SIGSEGV)使整个应用程序崩溃

每次我向 TreeView 插入文本时,我的应用程序都会调用它,这样我就可以一直处于关闭状态(您正在向某个窗口插入文本,并且您想查看最新的文本,例如在聊天中)

文本仅从主线程插入,并且此函数也仅在主线程中调用,因此这与我自己的应用程序中的多线程无关,但是我发现 TextView 正在与应用程序的其余部分异步呈现文本。就像负责绘制和处理文本的线程并不是真正的主线程一样。例如,如果我将一个巨大的文本加载到 TextView 中,我的应用程序正在响应,即使 TextView 以某种方式加载了文本。

出于这个原因,我相信 TextView 实际上正在使用自己的单独线程,并且当我尝试滚动窗口时,该线程正在更改文本。正在更改的文本使 iter 无效,因此在我传递richTextBox.Buffer.EndIter给 TextView ScrollToBottom 函数的 IL 代码之间的某个地方,文本可能被这个外部线程更改并且 iter 无效,这就是我得到这个内存访问异常的原因。

这甚至可能是 GTK 中的一个错误,但我使用的是非常稳定的版本 (2.1.20),它随所有单声道版本一起提供,直到 mono3,甚至适用于所有 windows gtk# 版本。

有没有其他方法可以“安全地”向下滚动

4

1 回答 1

6

这似乎有效:

连接滚动到SizeAllocated事件的函数:

this.tv.SizeAllocated += new SizeAllocatedHandler(Scroll2);

创建滚动函数

public void Scroll2(object sender, Gtk.SizeAllocatedArgs e)
{
    tv.ScrollToIter(tv.Buffer.EndIter, 0, false, 0, 0);
}

我不知道它是否正确,但到目前为止它并没有让我崩溃,并且一旦渲染完成它总是滚动到底部

于 2013-04-16T12:09:24.233 回答