none
.NET bug? - The Undo operation encountered a context that is different from what was applied in the corresponding Set operation.

    Question

  • Hello,

    I have tried to find a solution for this problem but so far have not found anything that applies to my exception.

    This is the message in my exception:

    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)."

    It occurs right after I perform any calls on a Socket that use threading (Begin...). The exception occured suddenly after I upgraded from .NET 2.0 beta2 to the final version of .NET 2.0, consider the following code.

    System.Net.EndPoint ep;
    ep = new System.Net.IPEndPoint(host, Convert.ToInt32(port));
    mainSock = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    mainSock.BeginConnect(ep, new System.AsyncCallback(DoneConnecting), mainSock);

    (host and port are Strings, mainSock is a socket) During execution, right after the execution point leaves the function (there is no code following this in the function) the Debugger comes up with the following error:

    System.InvalidOperationException was unhandled
      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)."
      Source="mscorlib"
      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)
           at System.Net.ContextAwareResult.Complete(IntPtr userToken)
           at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
           at System.Net.Dns.ResolveCallback(Object context)
           at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)

    People have commented on the DNS line, however, this code is not executed until the DNS has finished resolving the address. However, should it apply, here is the DNS lookup code I use.

    Dns.BeginGetHostEntry(Host, new AsyncCallback(DoneWithDNS), mainSock);

    Then after it finishes, this is how I process the result:

    ih = Dns.EndGetHostEntry(ar);
    ia = ih.AddressList;
    host = (IPAddress)ia.GetValue(0);

    The problem is that the spot the Exception is thrown is in [External Code], so I don't know anything about the area it is going wrong. If I convert my connect to not use BeginConnect(), the problem pops up later when I use BeginReceive(). I have noticed that sometimes, if I put a breakpoint in the function with BeginConnect(), and I take a really long time to step through the code, it will continue without a problem. It does however raise the same Exception once it tries to execute BeginReceive().

    I'm at a total loss as to what I should or can do. My guess is that it's possible that there is a problem with Threads and Sockets, but I really don't know for sure.

    My project is at a total stand still as it is an important component. Reverting back to using non Begin..() functions basically "fixes" the problem, but it does not help me at all. I need this functions to execute and have my program respond as well.

    .NET Framework 2.0 and Visual C# 2005 Express

    Wednesday, February 22, 2006 6:07 PM

Answers

All replies

  • Wednesday, February 22, 2006 8:11 PM
    Moderator
  • public void DoneConnecting(System.IAsyncResult ar) {
                mainSock.EndConnect(ar);


    It's the first thing I do, yeah.

    After some random attempts at trying things, I noticed that if I used Invoke on the functions that use the Begin...(), I got it to go away for a while. But it has returned again.

    From what I understand so far, I think one of the thread things I do before does not finish yet, or does not finish properly.

    Is it possible that my use of a global socket messes this up? It's a single connection, hence using a global (to the component) socket.
    Wednesday, February 22, 2006 10:53 PM
  • You're passing your socket object as the state object parameter to the BeginConnect call.  I would suggest changing your DoneConnecting() method to:

    private static void DoneConnecting(IAsyncResult ar)
    {
    // Retrieve the socket from the state object.
    Socket client = (Socket)ar.AsyncState;
    // Complete the connection.
    client.EndConnect(ar);
    }
    Thursday, February 23, 2006 1:45 AM
    Moderator
  • I changed that now, but it seems that the problem still persists.

    I really can't see anything I'm doing wrong. But no one seems to know anything specifically about this issue?
    Thursday, March 02, 2006 11:07 PM
  • Apparently I have found a way around the problem.

    I put in a check in each asynchronous function to see whether I needed an Invoke, and if I did, the function invoked itself on the component it was part of. For some reason this fixed the entire problem, and my project is currently running again.
    Friday, March 03, 2006 1:11 AM
  • >> a check in each asynchronous function to see whether I needed an Invoke, and if I did, the function invoked itself on the component it was part of

    could u post the code to do this

    Wednesday, August 23, 2006 6:55 AM
  • Hello,

    I don't have the code with me currently. But the basic idea is this.

    In the offending function, before anything happens, place the following code:

    if (this.InvokeRequired()) {
        this.Invoke( ... proper parameters to call itself with delegate etc. ... );
        return;
    }

    Hope that is of any help.
    Wednesday, August 23, 2006 4:57 PM
  • thanks!
    Thursday, August 24, 2006 11:46 AM