TextBox ScrollToCaret 导致线程混乱
显然,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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
即使您按照微软的建议来操作该控件,它仍然可能会给您带来意想不到的高 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.