TextBox ScrollToCaret 导致线程混乱

发布于 2024-10-14 23:45:26 字数 922 浏览 4 评论 0原文

显然,System.Windows.Forms.RichTextBox.ScrollToCaret 可能会导致在其调用中处理其他事件。当放置在事件处理程序中时,它可以使代码看起来以多事件(不是真正的多线程,但同样令人困惑)方式运行,从而导致竞争条件。提前为缺少细节表示歉意:

1) Windows 窗体应用程序 .NET C# 3.5

2) 创建 Canvas 和 RichTextBox

3) 启动一个以 30fps 调用 canvas.Invalidate() 的工作线程。

4) 捕获画布的OnMouseMove() 和Paint()。

5) 在 OnMouseMove 中将附加文本附加到 RichTextBox 并调用 ScrollToCaret()。

6) 在 OnMouseMove 和 OnPaint 的顶部和底部使用静态短 _eventdepth ++。

7) 当_eventdepth的值>时陷阱1. 堆栈跟踪:

   Canvas::OnPaint()
   [External Code] 
   Canvas::OnMouseMove(),  scrollToCaret() is within

此行为是否已记录并且应该像这样工作 - 是否有“GUI”调用将分发“子”事件?分享这个以防其他人开始浪费时间或者万一我误解了发生的事情。

--- 编辑 ---

我现在还使用 BeginInvoke 包装了从辅助线程对 canvas.Invalidate (步骤 3)的调用。我还有一个锁,当发生这种情况时,窗口开始分派其他事件(在同一主线程中)作为解决方案而不是阻塞(并像我预期的那样挂起)。

ScrollToCaret() 仍然会导致从同一堆栈中调用 OnPaint()。对于 Windows 程序员来说,哪些方法可能会触发额外的事件调度是显而易见的吗?

Apparently System.Windows.Forms.RichTextBox.ScrollToCaret can cause additional events to be processed within its call. When placed within an event handler it can make code appear to run in a multievent (not really multithreaded but just as confusing) fashion causing race conditions. Apologizing in advance for missing details:

1) Windows form app .NET C# 3.5

2) Create a Canvas and RichTextBox

3) Start a worker thread that calls canvas.Invalidate() at 30fps.

4) Capture OnMouseMove() and Paint() for the canvas.

5) Within OnMouseMove append append text to a RichTextBox and call ScrollToCaret().

6) Use a static short _eventdepth that ++ at top and -- at bottom of each of OnMouseMove and OnPaint.

7) Trap when the value of _eventdepth > 1. Stack Trace:

   Canvas::OnPaint()
   [External Code] 
   Canvas::OnMouseMove(),  scrollToCaret() is within

Is this behavior documented and supposed to work like this--are there are "GUI" calls that will distribute "child" events? Sharing this in case some one else starts burning time on it or in case I am misunderstanding whats happening.

--- edit ---

I have also now wrapped the call to canvas.Invalidate (step 3) from the secondary thread with BeginInvoke. I also had a lock that was blocking when that happens windows begins to dispatch additional events (in the same primary thread) as a solution rather than block (and hang like I would have expected).

The ScrollToCaret() still causes OnPaint() to be called from within the same stack. Is it just obvious to to windows programmers which methods may trigger additional event dispatches?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

胡渣熟男 2024-10-21 23:45:26

即使您按照微软的建议来操作该控件,它仍然可能会给您带来意想不到的高 CPU 使用率并挂起(原因似乎是在 riched20.dll 内部)。

所以我建议您使用简单的 TextBox 或完全切换到 WPF。

Even if you follow Microsoft's recommendation to manipulate the control, it can still give you unexpected high CPU usage and hang (the cause seems to be inside riched20.dll.

So I suggest you use a simple TextBox or switch to WPF completely.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文