Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 套接字/线程问题:撤消操作遇到的上下文与相应集合操作中应用的上下文不同_.net_Multithreading_Sockets_Thread Safety_Invalidoperationexception - Fatal编程技术网

.net 套接字/线程问题:撤消操作遇到的上下文与相应集合操作中应用的上下文不同

.net 套接字/线程问题:撤消操作遇到的上下文与相应集合操作中应用的上下文不同,.net,multithreading,sockets,thread-safety,invalidoperationexception,.net,Multithreading,Sockets,Thread Safety,Invalidoperationexception,我对上面的错误有很多疑问。我们有一个TCP/IP服务器应用程序,多年来一直运行良好。现在,我需要允许应用程序接受来自直接连接的USB设备的连接,方法是在内部使用套接字连接,以便在服务器应用程序中修补到localhost(127.0.0.1)。(顺便说一句,我提到USB只是为了解释我为什么这么做-我禁用了所有USB功能作为调试这个问题的一部分) 此套接字上的通信可能导致对客户端和服务器端GUI元素的调用。访问客户端上的GUI元素会导致标题中出现错误(下面的调用堆栈)。这里的一个关键问题是调试器无法

我对上面的错误有很多疑问。我们有一个TCP/IP服务器应用程序,多年来一直运行良好。现在,我需要允许应用程序接受来自直接连接的USB设备的连接,方法是在内部使用套接字连接,以便在服务器应用程序中修补到localhost(127.0.0.1)。(顺便说一句,我提到USB只是为了解释我为什么这么做-我禁用了所有USB功能作为调试这个问题的一部分)

此套接字上的通信可能导致对客户端和服务器端GUI元素的调用。访问客户端上的GUI元素会导致标题中出现错误(下面的调用堆栈)。这里的一个关键问题是调试器无法在异常时停止:尽管所有异常都设置为在抛出时停止,但应用程序只是在错误发生时终止

我的应用程序唯一独特之处在于它使用内部套接字连接到127.0.0.1。我还确认,如果将客户端分离为单独的应用程序,则该应用程序可以正常工作。然而,由于其他原因,我不能将此作为永久解决方案

下面我列出了几个讨论这类问题的帖子。不幸的是,在我的情况下,似乎没有一个解决方案:

  • 大多数相关文章都讨论了通过使用Invoke或BeginInvoke确保所有GUI操作都在GUI线程上执行的必要性。我确信我的应用程序能够正确地执行此操作(它使用application.Forms获取一个表单以获取主表单并在此基础上调用Invoke),并且在调试器中进行了双重检查。
  • 关于上述内容,有一些关于使用Invoke vs BeginInvoke来阻止/不阻止的讨论。在我的例子中,两者都有相同的结果。
  • 一些帖子建议有必要在GUI线程上自己创建套接字(我的是)。
  • 说明如果在应用程序中使用DoEvents(我不使用),则可能会出现错误。
  • 这还意味着,当使用异步调用进行客户端套接字连接(我的客户端连接是同步的)时,可能会出现缺少EndConnect调用的错误。
  • 说明如果尚未创建窗口句柄,则可能会从InvokeRequest获得不正确的结果(已使用IsHandleCreated对此进行了检查)。
  • 报告了一个类似的错误,但没有解决方案(微软自2006年以来一直在“调查”!)
  • 包含使用AsyncOperationManager.SynchronizationContext备份/还原同步上下文的建议,这(毫不奇怪?)只会导致不同的错误。
  • 有几篇文章建议该错误仅为调试错误,以下内容将使其消失-但我没有费心尝试:
    System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls=false
还有其他帖子问类似的问题:,和。也很好

下面是一个代码片段-当客户端接收套接字数据时,这会导致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
我正在使用VB.NET2010和.NET4

谢谢你的帮助-我希望上面的综合帖子列表也能帮助其他人

提姆

调用堆栈:

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).
线程“”(0x148c)已退出,代码为0(0x0)。
系统。关键事务:0:http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/UnhandledUnhandled exceptionmyapp.vshost.exeSystem.InvalidOperationException,mscorlib,版本=4.0.0.0,区域性=中性,PublicKeyToken=B77A5C561934E089撤消操作遇到的上下文与相应集合操作中应用的上下文不同。可能的原因是在线程上设置了上下文,但未还原(撤消)。在System.Threading.SynchronizationContextSwitcher.Undo()中
在System.Threading.ExecutionContextSwitcher.Undo()中
位于System.Threading.ExecutionContext.runFinallyCode(对象用户数据,布尔异常Rown)
在System.Runtime.CompilerServices.RuntimeHelpers.ExecuteBackoutCodeHelper(对象backoutCode、对象userData、布尔异常Rown)
在System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode代码、CleanupCode backoutCode、Object userData)中运行
位于System.Threading.ExecutionContext.RunInternal(ExecutionContext ExecutionContext,ContextCallback回调,对象状态)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态,布尔ignoreSyncCtx)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态)
在System.Net.ContextAwareResult.Complete(IntPtr userToken)
在System.Net.LazyAsyncResult.ProtectedInvokeCallback(对象结果,IntPtr userToken)
位于System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32错误代码,UInt32个字节,NativeOverlapped*NativeOverlapped)
在System.Threading.\u IOCompletionCallback.PerformiCompletionCallback(UInt32错误代码,UInt32 numBytes,NativeOverlapped*pOVERLAP)System.InvalidOperationException:撤消操作遇到的上下文与相应集合操作中应用的上下文不同。可能的原因是在线程上设置了上下文,但未还原(撤消)。
在System.Threading.SynchronizationContextSwitcher.Undo()中
在System.Threading.ExecutionContextSwitcher.Undo()中
位于System.Threading.ExecutionContext.runFinallyCode(对象用户数据,布尔异常Rown)
在System.Runtime.CompilerServices.RuntimeHelpers.ExecuteBackoutCodeHelper(对象backoutCode、对象userData、布尔异常Rown)
在System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode代码、CleanupCode backoutCode、Object userData)中运行
在System.Threading.ExecutionContext.RunInternal(ExecutionContext ExecutionContext,
    public static void ChangeSynchronizationContext(SynchronizationContext synchronizationContext, Action actionUnderSynchronizationContext)
    {
        var oldSyncContext = SynchronizationContext.Current;
        SynchronizationContext.SetSynchronizationContext(synchronizationContext);

        try
        {
            actionUnderSynchronizationContext();
        }
        finally
        {
            SynchronizationContext.SetSynchronizationContext(oldSyncContext);
        }
    }
ChangeSynchronizationContext(null, () => { /* start io */ });
        if (currentThreadContext.m_NestedIOCount >= 50)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(this.WorkerThreadComplete));
            flag = true;
        }
        else
        {
            this.m_AsyncCallback(this);
        }