Winforms TextBox ScrollToCaret导致线程混乱

Winforms TextBox ScrollToCaret导致线程混乱,winforms,multithreading,events,textbox,richtextbox,Winforms,Multithreading,Events,Textbox,Richtextbox,显然,System.Windows.Forms.RichTextBox.ScrollToCaret会导致在其调用中处理其他事件。当放置在事件处理程序中时,它会使代码看起来以多事件(不是真正的多线程,但同样令人困惑)的方式运行,从而导致竞争条件。对遗漏的细节提前道歉: 1) Windows窗体应用程序.NET C#3.5 2) 创建画布和RichTextBox 3) 启动一个工作线程,以30fps的速度调用canvas.Invalidate() 4) 捕获画布的OnMouseMove()和Pain

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

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

2) 创建画布和RichTextBox

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

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

5) 在OnMouseMove中,向RichTextBox追加文本并调用ScrollToCaret()

6) 在OnMouseMove和OnPaint的顶部和底部使用一个静态的short _eventdepth++

7) 当_eventdepth的值大于1时陷阱。堆栈跟踪:

   Canvas::OnPaint()
   [External Code] 
   Canvas::OnMouseMove(),  scrollToCaret() is within
这个行为是否有文档记录并且应该像这样工作——是否存在将分发“子”事件的“GUI”调用?分享这些信息,以防其他人开始浪费时间,或者我误解了正在发生的事情

---编辑---

现在,我还使用BeginInvoke从辅助线程包装了对canvas.Invalidate(步骤3)的调用。我还有一个锁,当windows开始调度额外的事件(在同一主线程中)作为解决方案而不是阻塞(并像我预期的那样挂起)时,它会被阻塞


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

即使您按照Microsoft的建议操作该控件,它仍然会给您带来意外的高CPU使用率和挂起(原因似乎在riched20.dll中)

因此,我建议您使用一个简单的文本框或完全切换到WPF