在非UI线程上操作UI导致卡死的问题

查找创建控件的目标线程

  1. 使用“!threads”命令显示所有线程,获取UI线程号(STA的就一个)
  2. 使用“!<UI线程号>s”命令切换至UI线程
  3. 使用“!dumpstackobjects”显示线程堆栈上的所有对象,获取WindowsFormsSynchronizationContext对象的地址
  4. 使用“!do <synchronizationContext对象地址>”命令显示其数据结构,从成员destinationThreadRef获取指定了创建控件的目标线程的WeakReference对象的地址
  5. 使用“!dumpobject <WeakReference对象地址>”显示其数据结构,从成员m_handle获取创建控件的目标线程的句柄
  6. 使用“dd <目标线程的句柄> L1”命令显示此句柄中包含的线程地址
  7. 使用“!dumpobject <目标线程地址>”命令显示目标线程的数据结构,从成员m_ManagedThreadId获取目标线程的托管线程号
  8. 使用“?0n<托管线程号>”命令获取托管线程号的16进制数
  9. 再次使用“!threads”命令显示所有线程,将刚获取的托管线程号与ID栏匹配,获取左边栏的线程对应的序号
  10. 使用“~<线程序号>s”命令切换至此线程
  11. 使用“!clearstack”命令查看此线程的堆栈,看是在运行哪些代码

 

 

结论

控件只应在UI线程上创建

 

 

参考

Debugging Windows Forms Application Hangs During SystemEvents.UserPreferenceChanged
Windows Forms application freezes when system settings are changed or the workstation is locked

在非UI线程上操作UI导致卡死的问题

上一篇:对control file的学习笔记


下一篇:Delphi- 调用存储过程的方法