- 工作线程ID 会记录在内部的 destinationThreadRef 字段中,我们试探下 02d69164 。
0:000:x86> !do 02d69164Name:System.Windows.Forms.WindowsFormsSynchronizationContextFields:MTFieldOffsetType VTAttrValue Name...533c220440025228 ...ows.Forms.Control0 instance 02d69218 controlToSendTo5cef92d04002523c System.WeakReference0 instance 02d69178 destinationThreadRef0:000:x86> !DumpObj /d 02d69178Name:System.WeakReferenceMethodTable: 5cef92d0EEClass:5cabf0ccSize:12(0xc) bytesFile:C:WindowsMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dllFields:MTFieldOffsetType VTAttrValue Name5cee2bdc400070a4System.IntPtr1 instance111828 m_handle0:000:x86> !do poi(111828)Name:System.Threading.ThreadFields:MTFieldOffsetType VTAttrValue Name5cee163840018ca28System.Int321 instance9 m_ManagedThreadId ...
从上面的输出中可以看到,9号线程 曾经创建了不该创建的 Control,所以找出这个 Control 就是解决问题的关键,这也是最难的 。3. 如何找到问题 Control以我目前的技术实力,从 dump 中确实找不到,但我可以运行时监测,突破点就是一旦这个 Control 在工作线程中创建,底层会安排一个
WindowsFormsSynchronizationContext 以及 MarshalingControl 对象,我们拦截他们的生成构造就好了 。
为了方便讲述,先上一段测试代码,在 backgroundWorker1_DoWork 方法中创建一个 Button 控件 。
namespace WindowsFormsApp1{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e){Button btn = new Button();}private void Form1_Load(object sender, EventArgs e){}private void button1_Click(object sender, EventArgs e){backgroundWorker1.RunWorkerAsync();}}}
接下来在 MarshalingControl 的构造函数上下一个bp断点来自动化记录,观察 new Button 的时候是否命中 。0:007> !name2ee System_Windows_Forms_ni System.Windows.Forms.Application+MarshalingControl..ctorModule:5b9b1000Assembly:System.Windows.Forms.dllToken:0600554aMethodDesc:5b9fe594Name:System.Windows.Forms.Application+MarshalingControl..ctor()JITTED Code Address: 5bb5d1a40:007> bp 5bb5d1a4 "!clrstack; gc"0:007> gOS Thread Id: 0x249c (9)Child SPIP Call Site067ff2f0 5bb5d1a4 System.Windows.Forms.Application+MarshalingControl..ctor()067ff2f4 5bb70224 System.Windows.Forms.Application+ThreadContext.get_MarshalingControl()067ff324 5bb6fe5d System.Windows.Forms.WindowsFormsSynchronizationContext..ctor()067ff338 5bb6fd4d System.Windows.Forms.WindowsFormsSynchronizationContext.InstallIfNeeded()067ff364 5bb6e9a0 System.Windows.Forms.Control..ctor(Boolean)067ff41c 5bbcd5cc System.Windows.Forms.ButtonBase..ctor()067ff428 5bbcd531 System.Windows.Forms.Button..ctor()067ff434 02342500 WindowsFormsApp1.Form1.backgroundWorker1_DoWork(System.Object, System.ComponentModel.DoWorkEventArgs)067ff488 630ee649 System.ComponentModel.BackgroundWorker.OnDoWork(System.ComponentModel.DoWorkEventArgs) [f:ddNDPfxsrccompmodsystemcomponentmodelBackgroundWorker.cs @ 107]067ff49c 630ee55d System.ComponentModel.BackgroundWorker.WorkerThreadStart(System.Object) [f:ddNDPfxsrccompmodsystemcomponentmodelBackgroundWorker.cs @ 245]067ff6a0 7c69f036 [HelperMethodFrame_PROTECTOBJ: 067ff6a0] System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr, System.Object[], System.Object, System.Object[] ByRef)067ff95c 6197c82c System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage, System.Runtime.Remoting.Messaging.IMessageSink)067ff9b0 61978274 System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.DoAsyncCall() [f:ddndpclrsrcBCLsystemruntimeremotingremotingproxy.cs @ 760]067ff9bc 61978238 System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(System.Object) [f:ddndpclrsrcBCLsystemruntimeremotingremotingproxy.cs @ 753]067ff9c0 6104e7b4 System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object) [f:ddndpclrsrcBCLsystemthreadingthreadpool.cs @ 1274]067ff9c8 61078604 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [f:ddndpclrsrcBCLsystemthreadingexecutioncontext.cs @ 980]067ffa34 61078537 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [f:ddndpclrsrcBCLsystemthreadingexecutioncontext.cs @ 928]067ffa48 6104f445 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() [f:ddndpclrsrcBCLsystemthreadingthreadpool.cs @ 1252]067ffa5c 6104eb7d System.Threading.ThreadPoolWorkQueue.Dispatch() [f:ddndpclrsrcBCLsystemthreadingthreadpool.cs @ 820]067ffaac 6104e9db System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() [f:ddndpclrsrcBCLsystemthreadingthreadpool.cs @ 1161]067ffccc 7c69f036 [DebuggerU2MCatchHandlerFrame: 067ffccc]
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 水均益|当央视记者,清华大学读研究生,水均益养出了一个好女儿
- 超沙雕又可爱的图片头像,图片头像图片,沙雕搞笑头像图片大全-
- 利落极简最炫qq昵称 超炫qq名
- 潮汕女孩适合做老婆吗,娶一个潮汕女人做老婆什么感觉-
- 超简单的懒人电饭煲腊八焖饭! 腊八饭的家常做法
- 讨厌的人 却要天天见 怎么办,讨厌一个人但是又必须每天见怎么办-
- 陶渊明的最经典10句诗,陶渊明的经典诗句精选-
- 仙剑经典歌曲回顾:一首逍遥叹 逍遥叹简谱
- 卞之琳经典诗13首 卞之琳的诗
- 柯蓝|超搞笑,刘琳客串《大博弈》的原因,竟跟张萌柯蓝出演的理由相同