上記のよくあるエラーに問題があります。数年間正常に動作している TCP/IP サーバー アプリケーションがあります。次に、ソケット接続を内部的に使用してサーバー アプリケーション内の localhost (127.0.0.1) にパッチを適用することにより、アプリケーションが直接接続された USB デバイスからの接続を受け入れるようにする必要があります。(ところで、私がこれを行っている理由を説明するためだけに USB について言及します。この問題のデバッグの一環として、すべての USB 機能を無効にしました)。
このソケットに沿った通信により、クライアント側とサーバー側の両方で GUI 要素が呼び出される可能性があります。クライアント側で GUI 要素にアクセスすると、タイトルにエラーが発生します (以下のコール スタック)。ここでの重要な問題の 1 つは、デバッガーが例外で停止できないことです。すべての例外がスローされたときに停止するように設定されているにもかかわらず、エラーが発生すると、アプリケーションは単純に終了します。
私のアプリケーションの唯一の特徴は、内部ソケットを使用して 127.0.0.1 に接続していることです。また、クライアントを別のアプリケーションに分離した場合、アプリケーションが正常に動作することも確認しています。ただし、他の理由により、これを永続的な解決策として使用することはできません。
この種の問題について議論している投稿がいくつかあります。それらを以下にリストします。残念ながら、私の場合、解決策を提供するものはないようです:
- ほとんどの関連記事では、Invoke または BeginInvoke を使用して、すべての GUI 操作が GUI スレッドで実行されるようにする必要性について説明しています。私のアプリケーションはこれを正しく行い (Application.Forms を使用してフォームを取得し、メイン フォームを取得し、これに対して Invoke を呼び出します)、デバッガーでダブル チェックしたと確信しています。
- 上記に関連して、ブロックする/ブロックしないための Invoke と BeginInvoke の使用に関するいくつかの議論があります。私の場合、どちらも同じ結果になります。
- 一部の投稿では、GUI スレッドでソケット自体を作成する必要があることが示唆されています (私の場合)。
- これは、アプリケーションで DoEvents を使用するとエラーが発生する可能性があることを説明しています (私は使用しません)。
- これは、クライアント ソケット接続に非同期呼び出しを使用している場合 (私のクライアント接続は同期)、EndConnect 呼び出しが見つからないというエラーが発生する可能性があることも意味します。
- これは、ウィンドウ ハンドルがまだ作成されていない場合に InvokeRequired から誤った結果が得られる可能性があることを説明しています (これは IsHandleCreated で確認済みです)。
- これは microsoft connectで同様のバグを報告していますが、解決策はありません (microsoft は 2006 年から「調査」しています!)
- これには、AsyncOperationManager.SynchronizationContext を使用して同期コンテキストをバックアップ/復元するという提案が含まれていますが、これは (当然のことですが?) さまざまなエラーを引き起こすだけです。
- エラーがデバッグのみであることを示唆する投稿がいくつかありますが、次のようにすれば解消されますが、それを試してみることはありませんでした:
System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false
同様の質問をしている他の投稿があります: here、here、およびhere。ここもいいもの。
以下にコード スニペットを示します。クライアントがソケット データを受信すると、ProcessCommandCT 内でクラッシュが発生します。
' Find application main form from any thread
' There is only one instance of 'RibbonForm1' and this is the main form
Public Function GetRibbonForm() As RibbonForm1
Dim rf As RibbonForm1 = Nothing
For Each f As Form In My.Application.OpenForms
rf = TryCast(f, RibbonForm1)
If rf IsNot Nothing Then Return rf
Next
Return Nothing
End Function
Public Sub ProcessCommandCT(ByVal cmd As String)
' code is peppered with these to debug this problem
Debug.Assert(GetRibbonForm.IsHandleCreated)
Debug.Assert(Not GetRibbonForm.InvokeRequired)
Try
Select Case cmd
Case "MYCMD"
Dim f As New Form
f.ShowDialog()
End Select
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub sock_Receive(ByVal msg As String) Handles sck.Receive
Dim rf As RibbonForm1 = GetRibbonForm
If rf.InvokeRequired Then
rf.BeginInvoke(New SubWithStringArgDelegate(AddressOf ProcessCommandCT), New Object() {msg})
Else
ProcessCommandCT(msg)
End If
End Sub
.NET4 で VB .NET 2010 を使用しています。
助けてくれてありがとう - 上記の投稿の統合リストが他の人にも役立つことを願っています.
ティム
コール スタック:
The thread '<No Name>' (0x148c) has exited with code 0 (0x0).
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>myapp.vshost.exe</AppDomain><Exception><ExceptionType>System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>The Undo operation encountered a context that is different from what was applied in the corresponding Set operation. The possible cause is that a context was Set on the thread and not reverted(undone).</Message><StackTrace> at System.Threading.SynchronizationContextSwitcher.Undo()
at System.Threading.ExecutionContextSwitcher.Undo()
at System.Threading.ExecutionContext.runFinallyCode(Object userData, Boolean exceptionThrown)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteBackoutCodeHelper(Object backoutCode, Object userData, Boolean exceptionThrown)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)</StackTrace><ExceptionString>System.InvalidOperationException: The Undo operation encountered a context that is different from what was applied in the corresponding Set operation. The possible cause is that a context was Set on the thread and not reverted(undone).
at System.Threading.SynchronizationContextSwitcher.Undo()
at System.Threading.ExecutionContextSwitcher.Undo()
at System.Threading.ExecutionContext.runFinallyCode(Object userData, Boolean exceptionThrown)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteBackoutCodeHelper(Object backoutCode, Object userData, Boolean exceptionThrown)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)</ExceptionString></Exception></TraceRecord>
The program '[6324] myapp.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).