[swf] Flow SynchronizationContext through ExecutionContext. Fixes #38599
authorMarek Safar <marek.safar@gmail.com>
Wed, 10 Feb 2016 19:24:13 +0000 (20:24 +0100)
committerMarek Safar <marek.safar@gmail.com>
Wed, 10 Feb 2016 19:24:13 +0000 (20:24 +0100)
mcs/class/System.Windows.Forms/System.Windows.Forms/AsyncMethodData.cs
mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs

index cbfeea4c763b0a2a53cc7c469e078dacfee96248..934823502df1e8fae4b63101bf60c1529184549f 100644 (file)
@@ -35,6 +35,7 @@ namespace System.Windows.Forms {
                public object [] Args;
                public AsyncMethodResult Result;
                public ExecutionContext Context;
+               public SynchronizationContext SyncContext;
        }
 
 }
index ff2427e069041443921e17fff29bb2903512acac..eb0fecfdb87090e0a300617186eb39ca2be8f84f 100644 (file)
@@ -468,11 +468,10 @@ namespace System.Windows.Forms {
 #endregion     // XplatUI Driver Methods
        }
 
-       internal class XplatUIDriverSupport {
+       static class XplatUIDriverSupport {
                #region XplatUI Driver Support Methods
-               internal static void ExecutionCallback (object state)
+               internal static void ExecutionCallback (AsyncMethodData data)
                {
-                       AsyncMethodData data = (AsyncMethodData) state;
                        AsyncMethodResult result = data.Result;
                        
                        object ret;
@@ -492,6 +491,25 @@ namespace System.Windows.Forms {
                        }
                }
 
+               static void ExecutionCallbackInContext (object state)
+               {
+                       AsyncMethodData data = (AsyncMethodData) state;
+
+                       if (data.SyncContext == null) {
+                               ExecutionCallback (data);
+                               return;
+                       }
+
+                       var oldContext = SynchronizationContext.Current;
+                       SynchronizationContext.SetSynchronizationContext (data.SyncContext);
+
+                       try {
+                               ExecutionCallback (data);
+                       } finally {
+                               SynchronizationContext.SetSynchronizationContext (oldContext);
+                       }
+               }
+
                internal static void ExecuteClientMessage (GCHandle gchandle)
                {
                        AsyncMethodData data = (AsyncMethodData) gchandle.Target;
@@ -499,7 +517,8 @@ namespace System.Windows.Forms {
                                if (data.Context == null) {
                                        ExecutionCallback (data);
                                } else {
-                                       ExecutionContext.Run (data.Context, new ContextCallback (ExecutionCallback), data);
+                                       data.SyncContext = SynchronizationContext.Current;
+                                       ExecutionContext.Run (data.Context, new ContextCallback (ExecutionCallbackInContext), data);
                                }
                        }
                        finally {