Note that there are some explanatory texts on larger screens.

plurals
  1. POSocket/threading problem: The Undo operation encountered a context that is different from what was applied in the corresponding Set operation
    text
    copied!<p>I'm having problems with the above much asked-about error. We have a TCP/IP server application which has been working fine for some years. I now need to allow the application to accept connections from directly connected USB devices, by internally using a socket connection to patch through to localhost (127.0.0.1) within the server application. (BTW I mention the USB only to explain why I am doing this - I disabled all USB functions as part of debugging this problem). </p> <p>The communications along this socket can result in calls to GUI elements on both the client and the server side. Accesses to GUI elements on the client side cause the error in the title (call stack below). One of the key problems here is that the debugger is unable to halt on the exception: despite all exceptions being set to halt when thrown the application simply terminates when the error occurs.</p> <p>The only thing that seems unique about my application is that it uses an internal socket to connect to 127.0.0.1. I have also confirmed that the application works fine if the client is separated into a separate application. However, I can't use this as a permanent solution for other reasons. </p> <p>There are several posts discussing this sort of problem which I have listed below. Unfortunately none seem to provide a solution in my case:</p> <ul> <li>Most related posts discuss the need to ensure that all GUI operations are performed on the GUI thread, by using Invoke or BeginInvoke. I am confident my application does this correctly (it obtains a form using Application.Forms to get the main form and calls Invoke on this) and have double checked in the debugger. <li> Relating to the above, there is some discussion as to the use of Invoke vs BeginInvoke in order to block/not block. In my case both have the same result. <li>Some posts suggest it is necessary to create the sockets themselves on the GUI thread (mine are). <li><a href="http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/48b4a763-7387-46da-8fc2-3e885670f62c" rel="nofollow noreferrer">This one</a> explains that you can get the error if you use DoEvents in your application (I don't). <li><a href="http://social.msdn.microsoft.com/Forums/en-US/clr/thread/270504db-76c3-4b0e-8b98-1d0bd4ce0258" rel="nofollow noreferrer">This one</a> also implies that you could get the error with a missing EndConnect call when using asynchronous calls for client socket connection (my client connection is synchronous). <li><a href="http://www.eggheadcafe.com/software/aspnet/30443269/how-to-use-invokerequired-when-in-the-middle-of-a-dll.aspx" rel="nofollow noreferrer">This one</a> explains that you can get incorrect results from InvokeRequired if the window handle is not yet created (have checked this with IsHandleCreated). <li><a href="http://connect.microsoft.com/VisualStudio/feedback/details/95006/the-undo-operation-encountered-a-context-that-is-different-from-what-was-applied-in-the-corresponding-set-operation" rel="nofollow noreferrer">This one on microsoft connect</a> reports a similar sounding bug but doesnt have a solution (microsoft have been 'investigating' it since 2006!) <li><a href="https://stackoverflow.com/questions/1736677/interacting-with-the-ui-thread-from-an-async-callback-method">This one</a> contains a suggestion to use AsyncOperationManager.SynchronizationContext to backup/restore the synchronsiation context, which (unsurprisingly?) just causes different errors. <li>There are a couple of posts that suggest that the error is debug only, and the following will make it go away - but I haven't bothered trying that:<br> System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false </ul> <p>There are other posts asking similar questions: <a href="https://stackoverflow.com/questions/2835273/invalidoperationexception-the-undo-operation-encountered-a-context-that-is-diffe">here</a>, <a href="https://stackoverflow.com/questions/457237/run-code-on-ui-thread-without-control-object-present">here</a> and <a href="https://stackoverflow.com/questions/1736677/interacting-with-the-ui-thread-from-an-async-callback-method">here</a>. A good one <a href="https://stackoverflow.com/questions/1274389/a-random-cross-thread-operation-exception-for-winforms-multithreaded-ui-operation">here</a> too.</p> <p>Here is a code snippet - this causes a crash within ProcessCommandCT when socket data is received by the client:</p> <pre><code>' 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 </code></pre> <p>I'm using VB .NET 2010 with .NET4.</p> <p>Thanks for any help - I hope the consolidated list of posts above also helps others.</p> <p>Tim</p> <p>Call stack:</p> <pre><code>The thread '&lt;No Name&gt;' (0x148c) has exited with code 0 (0x0). System.Transactions Critical: 0 : &lt;TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"&gt;&lt;TraceIdentifier&gt;http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled&lt;/TraceIdentifier&gt;&lt;Description&gt;Unhandled exception&lt;/Description&gt;&lt;AppDomain&gt;myapp.vshost.exe&lt;/AppDomain&gt;&lt;Exception&gt;&lt;ExceptionType&gt;System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/ExceptionType&gt;&lt;Message&gt;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).&lt;/Message&gt;&lt;StackTrace&gt; 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)&lt;/StackTrace&gt;&lt;ExceptionString&gt;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)&lt;/ExceptionString&gt;&lt;/Exception&gt;&lt;/TraceRecord&gt; The program '[6324] myapp.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0). </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload