WPF切换界面时引发ContextSwitchDeadlock
背景
很多时候我们在做WPF应用开发的时候不可避免地要进行各种UI的切换,如果这个时候如果在UI线程中加入过多的代码逻辑就有可能造成界面的卡顿,如果是在调试模式下卡顿一会儿以后就会弹出ContextSwitchDeadlock的异常,就像下面的截图描述的那样,这个时候我们往往不知道问题到底出在了哪里,针对这个问题,网上很多的意见都是在 Debug-->Windows-->Exception Settings中去掉ContextSwitchDeadlock这个选项让VS在调试状态下不再弹出下面的提示,但终究是治标不治本,因为编译的exe中这个问题仍然存在,今天这篇文章就这个问题做一个详细的解释和说明。
图一 ContextSwitchDeadlock界面
注意关于操作UI线程的两条铁律:
1 不要在UI线程中进行过多耗时的操作。
2 不要在非UI线程中试图访问UI元素。
解决过程
在出现上述过程的时候,点击图一中OK 按钮而不是Continue,这样就能够正确地重现当前界面卡顿的时候到底代码执行在了何处,后面按照下面的步骤进行
1 通过右键单击工具栏停靠区域并select“debugging位置”,确保“Debug Location”工具栏处于活动状态。 如果它处于活动状态,则应该在工具栏中看到一个标记为“Thread”的下拉列表。
2 在Thread下拉列表中选择主线程(Main Thread)。
3 您现在应该在代码编辑器中看到阻止上下文切换的代码。
图二 VS工具栏选择主线程
4 分析原因
这个是最重要的一步,就是你在执行当前操作的时候并且卡主界面的时候,实际的代码还在主线程上面执行阻止上下文切换的代码,所以当你这个时候再进行UI操作的时候由于UI线程此时已经忙不过来了,所以UI界面必然发生卡顿的现象,所以分析到这里我们就能够找到问题的关键点:主线程上面执行阻止上下文切换的代码是否存在效率问题?是否可以使用多线程优化代码?带着这些问题我重新优化了阻止上下文切换的代码,然后再次重复之前的操作过程,发现之前卡顿的现象明显解除,至此整个过程分析完毕。
总结
上面的整篇文章复盘了整个现象出现的原因,通过完整的分析我们得知还是刚才提到的那两条关于UI线程的两条铁律,特别是第一点很多时候一不小心就容易在UI线程中进行复杂业务耗时操作,这个时候需要我们去耐心分析,剥离业务耗时操作,采用多线程或其它方式,这样我们才能够真正构建流畅的UI显示和操作效果。