2014-02-17 87 views
2

在C#/ .net中,當發生錯誤時,堆棧會記錄在Windows錯誤日誌中。但是,我的應用程序有很多跨線程調用。堆棧跟蹤似乎停止在每個Invoke(MarshalledInvoke)。c#:堆棧在調用時停止

例如:

我的堆棧:

Exception Info: Facebook.FacebookApiException 
Stack: 
at System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean) 
at System.Windows.Forms.Control.Invoke(System.Delegate, System.Object[]) 
at Test.TcpTest.InterpretData() 
at Test.TcpTest.Incoming(System.String) 
at Test.TcpTest.cLoop() 
at System.Threading.ThreadHelper.ThreadStart_Context(System.Object) 
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
at System.Threading.ThreadHelper.ThreadStart() 

的異常發生在碼被在堆棧進一步執行。但是,堆棧每次停在marshalledInvoke。

有什麼我可以做的繼續在調用堆棧?

回答

5

當您使用Control.Invoke()而不是Control.BeginInvoke()時,UI線程上引發的任何異常都會封送回您的工作線程並重新拋出。有一些信息丟失,你會得到最內在的例外。

使用Invoke()很少正確,通常會造成死鎖,混淆異常和延遲工作線程的潛在危險。在UI線程執行委託目標之前,它被阻塞。這可能需要一段時間。確保你確實需要它。如果你調用一個你需要的返回值的方法,這纔是真正必要的。這應該總是被避免。

您可以使用「調試+異常」調試這些異常,勾選「拋出」複選框以查看CLR異常。調試器現在停止在拋出異常的代碼處。

+0

使用調用來停止「跨線程操作無效:從一個線程以外的線程訪問控制」的錯誤。使用delegate.invoke/begininvoke是否也適用於這些異常? –

+2

不,委託的BeginInvoke方法在單獨的工作線程上運行代碼。這是明確**不是**你想要做什麼,你想在UI線程上運行代碼以避免「Cross-thread」異常。 –