示例#1
0
			static bool CheckProperty(
					SynchronizationContext context,
					string memberName,
					out object value,
					out string name)
			{
				PropertyInfo member = (memberName == null)
						? (context.GetType()
										.GetProperty("Dispatcher")
								?? context.GetType()
										.GetProperty("Thread"))
						: context.GetType()
							.GetProperty(memberName);
				if (member == null) {
					value = null;
					name = null;
					return false;
				}
				value = member.GetValue(context);
				name = member.Name;
				return true;
			}
示例#2
0
        public WaveOutEvent(WaveFileReader waveProvider)
        {
            //lipsync_editor.logfile.Log("WaveOutEvent()");

            _waveProvider = waveProvider;
            //lipsync_editor.logfile.Log(". format= " + _waveProvider.WaveFormat);

            _syncContext = SynchronizationContext.Current;             // TODO: what is that - looks like if !null another thread starts
            if (_syncContext != null)
            {
                string label = _syncContext.GetType().Name;
                if (label == "LegacyAspNetSynchronizationContext" ||
                    label == "AspNetSynchronizationContext")
                {
                    //lipsync_editor.logfile.Log(". syncContext= " + label);
                    //lipsync_editor.logfile.Log(". set syncContext NULL");
                    _syncContext = null;
                }
            }

            _callbackEvent = new AutoResetEvent(false);

            _waveOutLock = new object();

            MultimediaResult result;

            lock (_waveOutLock)
            {
                result = WaveInterop.waveOutOpenWindow(out _hWaveOut,
                                                       DEVICEID,
                                                       _waveProvider.WaveFormat,
                                                       _callbackEvent.SafeWaitHandle.DangerousGetHandle(),
                                                       IntPtr.Zero,
                                                       WaveInterop.WaveInOutOpenFlags.CallbackEvent);
            }
            MultimediaException.Try(result, "waveOutOpen");

            PlaybackState = PlaybackState.Stopped;

            _buffers = new WaveOutBuffer[BUFFERS];

            int bufferSize = calcBytesPerLatency((LATENCY * 2 + BUFFERS - 1) / BUFFERS);             // round up.

            //lipsync_editor.logfile.Log(". bufferSize= " + bufferSize);

            for (var i = 0; i != BUFFERS; ++i)
            {
                _buffers[i] = new WaveOutBuffer(_hWaveOut, bufferSize, _waveProvider, _waveOutLock);
            }
        }
示例#3
0
            public void OnCompleted(Action <object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
            {
                if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0)
                {
                    this.executionContext = ExecutionContext.Capture();
                }

                if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0)
                {
                    SynchronizationContext sc = SynchronizationContext.Current;
                    if (sc != null && sc.GetType() != typeof(SynchronizationContext))
                    {
                        this.scheduler = sc;
                    }
                    else
                    {
                        TaskScheduler ts = TaskScheduler.Current;
                        if (ts != TaskScheduler.Default)
                        {
                            this.scheduler = ts;
                        }
                    }
                }

                // Remember current state
                this.state = state;
                // Remember continuation to be executed on completed (if not already completed, in case of which
                // continuation will be set to CallbackCompleted)
                var previousContinuation = Interlocked.CompareExchange(ref this.continuation, continuation, null);

                if (previousContinuation != null)
                {
                    if (!ReferenceEquals(previousContinuation, CallbackCompleted))
                    {
                        throw new InvalidOperationException();
                    }

                    // Lost the race condition and the operation has now already completed.
                    // We need to invoke the continuation, but it must be asynchronously to
                    // avoid a stack dive.  However, since all of the queueing mechanisms flow
                    // ExecutionContext, and since we're still in the same context where we
                    // captured it, we can just ignore the one we captured.
                    executionContext = null;
                    this.state       = null; // we have the state in "state"; no need for the one in UserToken
                    InvokeContinuation(continuation, state, forceAsync: true);
                }

                cb.Add(() => continuation(state));
            }
            /// <summary>
            /// Initializes a new instance of the SynchronizationContextIdentifier class.
            /// </summary>
            /// <param name="context">The SynchronizationContext to extract identity for.</param>
            public SynchronizationContextIdentifier(SynchronizationContext context)
            {
                Context = context;

                if (!object.ReferenceEquals(context, null))
                {
                    Type contextType = context.GetType();
                    if (DispatcherSynchronizationContextName == contextType.Name)
                    {
                        FieldInfo dispatcherField = contextType.GetField(DispatcherFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
                        if (dispatcherField != null)
                        {
                            dispatcherObject = dispatcherField.GetValue(context);
                        }
                    }
                }
            }
示例#5
0
        /// <summary>
        /// Synchronizes a delegate and then binds it to this context, and returns an asynchronous, synchronized, bound, valid delegate.
        /// </summary>
        /// <remarks>
        /// <para>The bound delegate will first determine if it is still valid. If the bound delegate is valid, then it will invoke the contained delegate. If the bound delegate is invalid, it will do nothing.</para>
        /// <para>To invalidate all bound delegates, call the <see cref="Reset"/> method.</para>
        /// </remarks>
        /// <param name="action">The contained delegate. This delegate should not raise exceptions.</param>
        /// <param name="synchronizationContext">The object to use for synchronizing the delegate if necessary.</param>
        /// <param name="checkSynchronizationContextVerification">Whether to verify that <paramref name="synchronizationContext"/> does support <see cref="SynchronizationContextProperties.Synchronized"/>.</param>
        /// <returns>A valid delegate bound to the current context.</returns>
        /// <threadsafety>
        /// <para>The returned delegate may be executed on any thread except the thread that owns <paramref name="synchronizationContext"/>; it will synchronize itself with this <see cref="CallbackContext"/>.</para>
        /// </threadsafety>
        public Action AsyncBind(Action action, SynchronizationContext synchronizationContext, bool checkSynchronizationContextVerification)
        {
            if (checkSynchronizationContextVerification)
            {
                // Verify that the synchronization context provides synchronization
                SynchronizationContextRegister.Verify(synchronizationContext.GetType(), SynchronizationContextProperties.Synchronized);
            }

            // Create the bound delegate
            Action boundAction = this.Bind(action);

            // Return a synchronized wrapper for the bound delegate
            return(() =>
            {
                synchronizationContext.Send((state) => boundAction(), null);
            });
        }
示例#6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private static Func <System.Threading.SynchronizationContext, System.Web.HttpApplication> GetFindApplicationDelegate(SynchronizationContext context)
        {
            Func <System.Threading.SynchronizationContext, System.Web.HttpApplication> factory = null;
            Type type = context.GetType();

            if (!type.FullName.Equals("System.Web.LegacyAspNetSynchronizationContext"))
            {
                return(null);
            }
            ParameterExpression sourceExpression     = Expression.Parameter(typeof(System.Threading.SynchronizationContext), "context");
            Expression          sourceInstance       = Expression.Convert(sourceExpression, type);
            FieldInfo           applicationFieldInfo = type.GetField("_application", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            Expression          fieldExpression      = Expression.Field(sourceInstance, applicationFieldInfo);

            factory = Expression.Lambda <Func <System.Threading.SynchronizationContext, System.Web.HttpApplication> >(fieldExpression, sourceExpression).Compile();
            return(factory);
        }
示例#7
0
        /// <summary>
        /// Initializes the UI environment.
        /// </summary>
        public void InitializeUIEnvironment()
        {
            // Get and check ui synchronization context
            m_uiSynchronizationContext = SynchronizationContext.Current;
            if ((m_uiSynchronizationContext == null) ||
                (m_uiSynchronizationContext.GetType() == typeof(SynchronizationContext)))
            {
                throw new InvalidOperationException("Unable to initialize RKApplication object: No valid UI SynchronizationContext found!");
            }

            // Create the UI messenger
            m_uiMessenger = new SeeingSharpMessenger();
            m_uiMessenger.ApplyForGlobalSynchronization(
                SeeingSharpMessageThreadingBehavior.EnsureMainSyncContextOnSyncCalls,
                SeeingSharpConstants.THREAD_NAME_GUI,
                m_uiSynchronizationContext);
        }
示例#8
0
 public ExporterComposerWorker()
 {
     //Discarded unreachable code: IL_0002, IL_0006
     //IL_0003: Incompatible stack heights: 0 vs 1
     //IL_0007: Incompatible stack heights: 0 vs 1
     SingletonReader.PushGlobal();
     resolverInstance    = 1f;
     _DefinitionInstance = -1;
     base._002Ector();
     m_CollectionInstance = SynchronizationContext.Current;
     if (m_CollectionInstance != null && (m_CollectionInstance.GetType().Name == "LegacyAspNetSynchronizationContext" || m_CollectionInstance.GetType().Name == "AspNetSynchronizationContext"))
     {
         m_CollectionInstance = null;
     }
     _0001(300);
     _0002(2);
     m_WatcherInstance = new object();
 }
示例#9
0
        private void InitializeApartmentDetails()
        {
            // Only synchronization_context if thread is STA.
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
            {
                return;
            }

            synchronization_context = SynchronizationContext.Current;

            // Check whether the current context is a plain SynchronizationContext object
            // and handle this as if no context was set at all.
            if (synchronization_context != null &&
                synchronization_context.GetType() == typeof(SynchronizationContext))
            {
                synchronization_context = null;
            }
        }
        // Instantiate and install a WF op [....] context, and save off the old one.
        internal static void InstallIfNeeded()
        {
            // Exit if we shouldn't auto-install, if we've already installed and we haven't uninstalled,
            // or if we're being called recursively (creating the WF
            // async op [....] context can create a parking window control).
            if (!AutoInstall || inSyncContextInstallation)
            {
                return;
            }

            if (SynchronizationContext.Current == null)
            {
                previousSyncContext = null;
            }

            if (previousSyncContext != null)
            {
                return;
            }

            inSyncContextInstallation = true;
            try {
                SynchronizationContext currentContext = AsyncOperationManager.SynchronizationContext;
                //Make sure we either have no [....] context or that we have one of type SynchronizationContext
                if (currentContext == null || currentContext.GetType() == typeof(SynchronizationContext))
                {
                    previousSyncContext = currentContext;

                    // SECREVIEW : WindowsFormsSynchronizationContext.cctor generates a call to SetTopLevel on the MarshallingControl (hidden sycn hwnd),
                    //             this call demands TopLevelWindow (UIPermissionWindow.SafeTopLevelWindows) so an assert for that permission is needed here.
                    //             The assert is safe, we are creating a thread context and the [....] window is hidden.
                    new PermissionSet(PermissionState.Unrestricted).Assert();
                    try {
                        AsyncOperationManager.SynchronizationContext = new WindowsFormsSynchronizationContext();
                    }
                    finally {
                        CodeAccessPermission.RevertAssert();
                    }
                }
            }
            finally {
                inSyncContextInstallation = false;
            }
        }
        // Instantiate and install a WF op sync context, and save off the old one.
        internal static void InstallIfNeeded()
        {
            // Exit if we shouldn't auto-install, if we've already installed and we haven't uninstalled,
            // or if we're being called recursively (creating the WF
            // async op sync context can create a parking window control).
            if (!AutoInstall || inSyncContextInstallation)
            {
                return;
            }

            if (SynchronizationContext.Current == null)
            {
                previousSyncContext = null;
            }

            if (previousSyncContext != null)
            {
                return;
            }

            inSyncContextInstallation = true;
            try {
                SynchronizationContext currentContext = AsyncOperationManager.SynchronizationContext;
                //Make sure we either have no sync context or that we have one of type SynchronizationContext
                if (currentContext == null || currentContext.GetType() == typeof(SynchronizationContext))
                {
                    previousSyncContext = currentContext;

                    //


                    new PermissionSet(PermissionState.Unrestricted).Assert();
                    try {
                        AsyncOperationManager.SynchronizationContext = new WindowsFormsSynchronizationContext();
                    }
                    finally {
                        CodeAccessPermission.RevertAssert();
                    }
                }
            }
            finally {
                inSyncContextInstallation = false;
            }
        }
示例#12
0
        /// <summary>
        /// Synchronizes a delegate and then binds it to this context, and returns a synchronous, synchronized, bound, valid delegate.
        /// </summary>
        /// <remarks>
        /// <para>The bound delegate will first determine if it is still valid. If the bound delegate is valid, then it will invoke the contained delegate. If the bound delegate is invalid, it will do nothing.</para>
        /// <para>To invalidate all bound delegates, call the <see cref="Reset"/> method.</para>
        /// </remarks>
        /// <typeparam name="T">The return value of the contained and bound delegates.</typeparam>
        /// <param name="func">The contained delegate. This delegate should not raise exceptions.</param>
        /// <param name="synchronizationContext">The object to use for synchronizing the delegate.</param>
        /// <param name="checkSynchronizationContextVerification">Whether to verify that <paramref name="synchronizationContext"/> does support <see cref="SynchronizationContextProperties.Synchronized"/>.</param>
        /// <returns>A valid delegate bound to the current context.</returns>
        /// <threadsafety>
        /// <para>The returned delegate may be executed on any thread except the thread that owns <paramref name="synchronizationContext"/>; it will synchronize itself with this <see cref="CallbackContext"/>.</para>
        /// </threadsafety>
        public Func <T> Bind <T>(Func <T> func, SynchronizationContext synchronizationContext, bool checkSynchronizationContextVerification)
        {
            if (checkSynchronizationContextVerification)
            {
                // Verify that the synchronization context provides synchronization
                SynchronizationContextRegister.Verify(synchronizationContext.GetType(), SynchronizationContextProperties.Synchronized);
            }

            // Create the bound delegate
            Func <T> boundFunc = this.Bind(func);

            // Return a synchronized wrapper for the bound delegate
            return(() =>
            {
                T retVal = default(T);
                synchronizationContext.Send((state) => retVal = boundFunc(), null);
                return retVal;
            });
        }
示例#13
0
        public void OnCompleted(Action <object> continuation, object state, ValueTaskSourceOnCompletedFlags flags, out CompletionData completionData, out bool doubleCompletion)
        {
            completionData = default;

            doubleCompletion = false;
            Action <object> awaitableState = _completion;

            if (ReferenceEquals(awaitableState, s_awaitableIsNotCompleted))
            {
                _completion      = continuation;
                _completionState = state;

                // Capture the SynchronizationContext if there's any and we're allowing capture (from pipe options)
                if (_useSynchronizationContext && (flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0)
                {
                    SynchronizationContext sc = SynchronizationContext.Current;
                    if (sc != null && sc.GetType() != typeof(SynchronizationContext))
                    {
                        _synchronizationContext = SynchronizationContext.Current;
                    }
                }

                // Capture the execution context
                if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0)
                {
                    _executionContext = ExecutionContext.Capture();
                }
            }

            if (ReferenceEquals(awaitableState, s_awaitableIsCompleted))
            {
                completionData = new CompletionData(continuation, state, _executionContext, _synchronizationContext);
                return;
            }

            if (!ReferenceEquals(awaitableState, s_awaitableIsNotCompleted))
            {
                doubleCompletion = true;
                completionData   = new CompletionData(continuation, state, _executionContext, _synchronizationContext);
            }
        }
        private static Func <SynchronizationContext, HttpApplication> GetFindApplicationDelegate(SynchronizationContext context)
        {
            Delegate factory = null;
            Type     type    = context.GetType();

            if (!type.FullName.Equals("System.Web.LegacyAspNetSynchronizationContext"))
            {
                return(null);
            }
            //找到字段
            ParameterExpression sourceExpression = Expression.Parameter(typeof(SynchronizationContext), "context");
            //目前支持 System.Web.LegacyAspNetSynchronizationContext 内部类
            //查找        private HttpApplication _application 字段
            Expression sourceInstance       = Expression.Convert(sourceExpression, type);
            FieldInfo  applicationFieldInfo = type.GetField("_application", BindingFlags.NonPublic | BindingFlags.Instance);
            Expression fieldExpression      = Expression.Field(sourceInstance, applicationFieldInfo);

            factory = Expression.Lambda <Func <SynchronizationContext, HttpApplication> >(fieldExpression, sourceExpression).Compile();

            //返回委托
            return((Func <SynchronizationContext, HttpApplication>)factory);
        }
示例#15
0
        internal void StartInitialization()
        {
            // Store the main sync context, since we'll need later on for subscribing
            // add-in extension points (Mono.Addins isn't currently thread safe)
            mainContext = SynchronizationContext.Current;

            // If there is no custom threading context, we can't use background initialization since
            // we have no main thread into which to dispatch
            backgroundInitialize = mainContext != null && mainContext.GetType() != typeof(SynchronizationContext);

            if (backgroundInitialize)
            {
                // Initialize the service in a background thread.
                initializing = true;
                Thread t = new Thread(new ThreadStart(BackgroundInitialize))
                {
                    Name         = "Assembly service initialization",
                    IsBackground = true,
                };
                t.Start();
            }
        }
示例#16
0
 protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
 {
     if (creationThread == Thread.CurrentThread)
     {
         // We are running in the same thread, so just directly fire the collection changed notification.
         OnCollectionChangedInternal(e);
     }
     else if (creationSyncContext.GetType() == typeof(SynchronizationContext))
     {
         // We are running in free threaded context, also directly fire the collection changed notification.
         OnCollectionChangedInternal(e);
     }
     else
     {
         // We are running in WindowsFormsSynchronizationContext or DispatcherSynchronizationContext,
         // so we should marshal the collection changed notification back to the creation thread.
         // Note that we should use the blocking SynchronizationContext.Send operation to marshal the call,
         // because SynchronizationContext.Post will fail under heavy usage scenario.
         creationSyncContext.Send(delegate
         {
             OnCollectionChangedInternal(e);
         }, null);
     }
 }
示例#17
0
        /// <summary>
        /// Executes the given action after the given amount of time.
        /// </summary>
        /// <param name="action">The action to be executed.</param>
        /// <param name="delayTime">The delay time to be passed before executing the given action.</param>
        /// <param name="forceValidSyncContext">True to force a valid (UI) SynchronizationContext.</param>
        public static async void InvokeDelayed(Action action, TimeSpan delayTime, bool forceValidSyncContext = true)
        {
            action.EnsureNotNull(nameof(action));
            delayTime.EnsureLongerThanZero(nameof(delayTime));

            // Gets current Synchronization context
            if (forceValidSyncContext)
            {
                SynchronizationContext syncContext = SynchronizationContext.Current;
                if (syncContext == null)
                {
                    throw new SeeingSharpException("No SynchronizationContext is available on current thread!");
                }
                if (syncContext.GetType() == typeof(SynchronizationContext))
                {
                    throw new SeeingSharpException("This method is not available on default synchronization context!");
                }
            }

            // Wait specified time
            await Task.Delay(delayTime);

            action();
        }
示例#18
0
            private static void QueueContinuation(Action continuation, bool flowContext)
            {
                if (continuation == null)
                {
                    throw new ArgumentNullException("continuation");
                }
                if (TplEtwProvider.Log.IsEnabled())
                {
                    continuation = YieldAwaitable.YieldAwaiter.OutputCorrelationEtwEvent(continuation);
                }
                SynchronizationContext currentNoFlow = SynchronizationContext.CurrentNoFlow;

                if (currentNoFlow != null && currentNoFlow.GetType() != typeof(SynchronizationContext))
                {
                    currentNoFlow.Post(YieldAwaitable.YieldAwaiter.s_sendOrPostCallbackRunAction, (object)continuation);
                }
                else
                {
                    TaskScheduler current = TaskScheduler.Current;
                    if (current == TaskScheduler.Default)
                    {
                        if (flowContext)
                        {
                            ThreadPool.QueueUserWorkItem(YieldAwaitable.YieldAwaiter.s_waitCallbackRunAction, (object)continuation);
                        }
                        else
                        {
                            ThreadPool.UnsafeQueueUserWorkItem(YieldAwaitable.YieldAwaiter.s_waitCallbackRunAction, (object)continuation);
                        }
                    }
                    else
                    {
                        Task.Factory.StartNew(continuation, new CancellationToken(), TaskCreationOptions.PreferFairness, current);
                    }
                }
            }
 private static bool IsApplicable(SynchronizationContext context)
 {
     return(context?.GetType().FullName == "System.Windows.Threading.DispatcherSynchronizationContext");
 }
 private static bool IsApplicable(SynchronizationContext context)
 {
     return(context?.GetType().FullName == "System.Windows.Forms.WindowsFormsSynchronizationContext");
 }
示例#21
0
        public void OnCompleted(Action <object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
        {
            if (continuation == null)
            {
                throw new ArgumentNullException(nameof(continuation));
            }
            ValidateToken(token);

            if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0)
            {
                _executionContext = ExecutionContext.Capture();
            }

            if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0)
            {
                SynchronizationContext sc = SynchronizationContext.Current;
                if (sc != null && sc.GetType() != typeof(SynchronizationContext))
                {
                    _capturedContext = sc;
                }
                else
                {
                    TaskScheduler ts = TaskScheduler.Current;
                    if (ts != TaskScheduler.Default)
                    {
                        _capturedContext = ts;
                    }
                }
            }

            object oldContinuation = _continuation;

            if (oldContinuation == null)
            {
                _continuationState = state;
                oldContinuation    = Interlocked.CompareExchange(ref _continuation, continuation, null);
            }

            if (oldContinuation != null)
            {
                if (!ReferenceEquals(oldContinuation, ManualResetValueTaskSourceCoreShared.s_sentinel))
                {
                    ManualResetValueTaskSourceCoreShared.ThrowInvalidOperationException();
                }

                switch (_capturedContext)
                {
                case null:
                    if (_executionContext != null)
                    {
                        // REVIEW: Original call was
                        // ThreadPool.QueueUserWorkItem(continuation, state, preferLocal: true);
                        ThreadPool.QueueUserWorkItem(s => continuation(s), state);
                    }
                    else
                    {
                        // REVIEW: Original call was
                        // ThreadPool.UnsafeQueueUserWorkItem(continuation, state, preferLocal: true);
                        ThreadPool.UnsafeQueueUserWorkItem(s => continuation(s), state);
                    }
                    break;

                case SynchronizationContext sc:
                    sc.Post(s =>
                    {
                        var tuple = (Tuple <Action <object>, object>)s;
                        tuple.Item1(tuple.Item2);
                    }, Tuple.Create(continuation, state));
                    break;

                case TaskScheduler ts:
                    Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, ts);
                    break;
                }
            }
        }
        /// <summary>Schedules the continuation onto the <see cref="Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
        /// <param name="task">The awaited task.</param>
        /// <param name="continuation">The action to invoke when the await operation completes.</param>
        /// <param name="continueOnCapturedContext">Whether to capture and marshal back to the current context.</param>
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="continuation"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="NullReferenceException">The awaiter was not properly initialized.</exception>
        /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
        internal static void OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext)
        {
            if (continuation == null)
            {
                throw new ArgumentNullException("continuation");
            }

            SynchronizationContext sc = continueOnCapturedContext ? SynchronizationContext.Current : null;

            if (sc != null && sc.GetType() != typeof(SynchronizationContext))
            {
                // When the task completes, post to the synchronization context, or run it inline if we're already in
                // the right place
                task.ContinueWith(
                    delegate
                {
                    try
                    {
                        sc.Post(state => ((Action)state)(), continuation);
                    }
                    catch (Exception exc)
                    {
                        AsyncServices.ThrowAsync(exc, null);
                    }
                },
                    CancellationToken.None,
                    TaskContinuationOptions.ExecuteSynchronously,
                    TaskScheduler.Default);
            }
            else
            {
                var scheduler = continueOnCapturedContext ? TaskScheduler.Current : TaskScheduler.Default;
                if (task.IsCompleted)
                {
                    Task.Factory.StartNew(
                        s => ((Action)s)(), continuation, CancellationToken.None, TaskCreationOptions.None, scheduler);
                }
                else
                {
                    // NOTE: There is a known rare race here.  For performance reasons, we want this continuation to
                    // execute synchronously when the task completes, but if the task is already completed by the time
                    // we call ContinueWith, we don't want it executing synchronously as part of the ContinueWith call.
                    // If the race occurs, and if the unbelievable happens and it occurs frequently enough to
                    // stack dive, ContinueWith's support for depth checking helps to mitigate this.
                    if (scheduler != TaskScheduler.Default)
                    {
                        // When the task completes, run the continuation in a callback using the correct task scheduler.
                        task.ContinueWith(
                            _ => RunNoException(continuation),
                            CancellationToken.None,
                            TaskContinuationOptions.ExecuteSynchronously,
                            scheduler);
                    }
                    else
                    {
                        // When the task completes, run the continuation in a callback using the correct task scheduler.
                        task.ContinueWith(
                            delegate
                        {
                            if (IsValidLocationForInlining)
                            {
                                RunNoException(continuation);
                            }
                            else
                            {
                                Task.Factory.StartNew(
                                    s => RunNoException((Action)s),
                                    continuation,
                                    CancellationToken.None,
                                    TaskCreationOptions.None,
                                    TaskScheduler.Default);
                            }
                        },
                            CancellationToken.None,
                            TaskContinuationOptions.ExecuteSynchronously,
                            TaskScheduler.Default);
                    }
                }
            }
        }
        private bool InvokeInSynchronizationContext(IInvocation invocation)
        {
            if (metaInfo != null)
            {
                IHandler handler = null;
                SynchronizationContext syncContext     = null;
                SynchronizationContext prevSyncContext = null;
                var methodInfo     = invocation.MethodInvocationTarget;
                var syncContextRef = metaInfo.GetSynchronizedContextFor(methodInfo);

                if (syncContextRef != null)
                {
                    switch (syncContextRef.ReferenceType)
                    {
                    case SynchronizeContextReferenceType.Key:
                        handler = kernel.GetHandler(syncContextRef.ComponentKey);
                        break;

                    case SynchronizeContextReferenceType.Interface:
                        handler = kernel.GetHandler(syncContextRef.ServiceType);
                        break;
                    }

                    if (handler == null)
                    {
                        throw new ApplicationException("The synchronization context could not be resolved.  Did you forget to register it in the container?");
                    }

                    syncContext = handler.Resolve(CreationContext.CreateEmpty()) as SynchronizationContext;

                    if (syncContext == null)
                    {
                        throw new ApplicationException(string.Format("{0} does not implement {1}",
                                                                     syncContextRef, typeof(SynchronizationContext).FullName));
                    }

                    prevSyncContext = SynchronizationContext.Current;
                }
                else
                {
                    syncContext = SynchronizationContext.Current;
                }

                if (syncContext != activeSyncContext)
                {
                    try
                    {
                        var result = CreateResult(invocation);

                        if (prevSyncContext != null)
                        {
                            SynchronizationContext.SetSynchronizationContext(syncContext);
                        }

                        if (syncContext.GetType() == typeof(SynchronizationContext))
                        {
                            InvokeSynchronously(invocation, result);
                        }
                        else
                        {
                            syncContext.Send(state =>
                            {
                                activeSyncContext = syncContext;
                                try
                                {
                                    InvokeSafely(invocation, result);
                                }
                                finally
                                {
                                    activeSyncContext = null;
                                }
                            }, null);
                        }
                    }
                    finally
                    {
                        if (prevSyncContext != null)
                        {
                            SynchronizationContext.SetSynchronizationContext(prevSyncContext);
                        }
                    }
                }
                else
                {
                    InvokeSynchronously(invocation, null);
                }

                return(true);
            }

            return(false);
        }
示例#24
0
        private void ResumeProcessing(IResumeMessageRpc resume)
        {
            bool alreadyResumedNoLock;

            resume.Resume(out alreadyResumedNoLock);

            if (alreadyResumedNoLock)
            {
                string text = SR.Format(SR.SFxMultipleCallbackFromSynchronizationContext, _context.GetType().ToString());
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(text));
            }
        }
示例#25
0
        private bool InvokeInSynchronizationContext(IInvocation invocation)
        {
            if (metaInfo == null)
            {
                return(false);
            }

            SynchronizationContext syncContext     = null;
            SynchronizationContext prevSyncContext = null;
            var methodInfo     = invocation.MethodInvocationTarget;
            var syncContextRef = metaInfo.GetSynchronizedContextFor(methodInfo);

            if (syncContextRef != null)
            {
                syncContext     = syncContextRef.Resolve(kernel, CreationContext.CreateEmpty());
                prevSyncContext = SynchronizationContext.Current;
            }
            else
            {
                syncContext = SynchronizationContext.Current;
            }

            if (syncContext != activeSyncContext)
            {
                try
                {
                    var result = CreateResult(invocation);

                    if (prevSyncContext != null)
                    {
                        SynchronizationContext.SetSynchronizationContext(syncContext);
                    }

                    if (syncContext.GetType() == typeof(SynchronizationContext))
                    {
                        InvokeSynchronously(invocation, result);
                    }
                    else
                    {
                        syncContext.Send(state =>
                        {
                            activeSyncContext = syncContext;
                            try
                            {
                                InvokeSafely(invocation, result);
                            }
                            finally
                            {
                                activeSyncContext = null;
                            }
                        }, null);
                    }
                }
                finally
                {
                    if (prevSyncContext != null)
                    {
                        SynchronizationContext.SetSynchronizationContext(prevSyncContext);
                    }
                }
            }
            else
            {
                InvokeSynchronously(invocation, null);
            }

            return(true);
        }
示例#26
0
            void MethodHasSameSyncContextTypeAsConstructor()
            {
                var asyncTestSyncContext = (AsyncTestSyncContext)SynchronizationContext.Current;

                Assert.IsType(synchronizationContext.GetType(), asyncTestSyncContext.GetInnerSyncContext());
            }
示例#27
0
 private static bool IsAspNetContext(this SynchronizationContext context)
 {
     //Maybe not the best way to detect the AspNetSynchronizationContext but it works for now
     return(context != null && context.GetType().FullName == "System.Web.AspNetSynchronizationContext");
 }
        /// <summary>Schedules the continuation action for this operation.</summary>
        /// <param name="continuation">The continuation to invoke when the operation has completed.</param>
        /// <param name="state">The state object to pass to <paramref name="continuation"/> when it's invoked.</param>
        /// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param>
        /// <param name="flags">The flags describing the behavior of the continuation.</param>
        public void OnCompleted(Action <object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
        {
            if (continuation == null)
            {
                throw new ArgumentNullException(nameof(continuation));
            }
            ValidateToken(token);

            if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0)
            {
                _executionContext = ExecutionContext.Capture();
            }

            if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0)
            {
                SynchronizationContext sc = SynchronizationContext.Current;
                if (sc != null && sc.GetType() != typeof(SynchronizationContext))
                {
                    _capturedContext = sc;
                }
                else
                {
                    TaskScheduler ts = TaskScheduler.Current;
                    if (ts != TaskScheduler.Default)
                    {
                        _capturedContext = ts;
                    }
                }
            }

            // We need to set the continuation state before we swap in the delegate, so that
            // if there's a race between this and SetResult/Exception and SetResult/Exception
            // sees the _continuation as non-null, it'll be able to invoke it with the state
            // stored here.  However, this also means that if this is used incorrectly (e.g.
            // awaited twice concurrently), _continuationState might get erroneously overwritten.
            // To minimize the chances of that, we check preemptively whether _continuation
            // is already set to something other than the completion sentinel.

            object oldContinuation = _continuation;

            if (oldContinuation == null)
            {
                _continuationState = state;
                oldContinuation    = Interlocked.CompareExchange(ref _continuation, continuation, null);
            }

            if (oldContinuation != null)
            {
                // Operation already completed, so we need to queue the supplied callback.
                if (!ReferenceEquals(oldContinuation, ManualResetValueTaskSourceCoreShared.s_sentinel))
                {
                    ManualResetValueTaskSourceCoreShared.ThrowInvalidOperationException();
                }

                switch (_capturedContext)
                {
                case null:
                    if (_executionContext != null)
                    {
                        ThreadPool.QueueUserWorkItem(continuation, state, preferLocal: true);
                    }
                    else
                    {
                        ThreadPool.UnsafeQueueUserWorkItem(continuation, state, preferLocal: true);
                    }
                    break;

                case SynchronizationContext sc:
                    sc.Post(s =>
                    {
                        var tuple = (Tuple <Action <object>, object>)s;
                        tuple.Item1(tuple.Item2);
                    }, Tuple.Create(continuation, state));
                    break;

                case TaskScheduler ts:
                    Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, ts);
                    break;
                }
            }
        }
示例#29
0
        // This is executed on Awesomium's thread.
        static void TakeSnapshots(WebView view, int messageLine, bool exit = true)
        {
            if (!view.IsLive)
            {
                // Dispose the view.
                view.Dispose();
                return;
            }

            // Get the hostname. If it's empty, it must be our JS Console that saves.
            string host = String.IsNullOrEmpty(view.Source.Host) ? "JS" : view.Source.Host;

            // A BitmapSurface is assigned by default to all WebViews.
            BitmapSurface surface = (BitmapSurface)view.Surface;
            // Build a name for the saved image.
            string imageFile = String.Format("{0}.{1:yyyyMMddHHmmss}.png", host, DateTime.Now);

            // Save the buffer to a PNG image.
            surface.SaveToPNG(imageFile, true);
            // Print message.
            ReplaceLine(String.Format("Saved: {0}", imageFile), messageLine + 2);

            // Check if we can execute JavaScript
            // against the DOM.
            if (!view.IsDocumentReady)
            {
                // Print message.
                ReplaceLine("DOM not available.", messageLine + 1);

                if (!exit)
                {
                    return;
                }

                // Dispose the view.
                view.Dispose();
                savingSnapshots--;
                return;
            }

            // We demonstrate resizing to full height.
            ReplaceLine("Attempting to resize to full height... ", messageLine + 1);

            // This JS call will normally return the full height
            // of the page loaded.
            int docHeight = (int)view.ExecuteJavascriptWithResult(PAGE_HEIGHT_FUNC);

            // ExecuteJavascriptWithResult is a synchronous call. Synchronous
            // calls may fail. We check for errors that may occur. Note that
            // if you often get a Error.TimedOut, you may need to set the
            // IWebView.SynchronousMessageTimeout property to a higher value
            // (the default is 800ms).
            Error lastError = view.GetLastError();

            // Report errors.
            if (lastError != Error.None)
            {
                ReplaceLine(String.Format("Error: {0} occurred while getting the page's height.", lastError), messageLine + 1);
            }

            // Exit if the operation failed or the height is 0.
            if (docHeight == 0)
            {
                return;
            }

            // No more content to display.
            if (docHeight == view.Height)
            {
                // Print message.
                ReplaceLine("Full height already loaded.", messageLine + 1);

                if (!exit)
                {
                    return;
                }

                // Dispose the view.
                view.Dispose();
                savingSnapshots--;
                return;
            }

            // All predefined surfaces of Awesomium.NET,
            // support resizing. Here is a demonstration.
            surface.Resized += (s, e) =>
            {
                // Print message.
                ReplaceLine("Surface Resized", messageLine + 1);
                // Build a name for the saved image.
                string fullImageFile = String.Format("{0}.{1:yyyyMMddHHmmss}.full.png", host, DateTime.Now);
                // Save the updated buffer to a new PNG image.
                surface.SaveToPNG(fullImageFile, true);
                // Print message.
                ReplaceLine(String.Format("Saved: {0}", fullImageFile), messageLine + 2);

                // Get Awesomium's synchronization context. You can only
                // acquire this from Awesomium's thread, but you can then
                // cache it or pass it to another thread to be used for
                // safe cross-thread calls to Awesomium. Here we just
                // demonstrate using Post to postpone the view's destruction
                // till the next update pass of the WebCore.
                SynchronizationContext syncCtx = SynchronizationContext.Current;

                // Check if a valid SynchronizationContext is available.
                if ((syncCtx != null) && (syncCtx.GetType() != typeof(SynchronizationContext)))
                {
                    // Queue the destruction of the view. Code execution
                    // will resume immediately (so we exit the event handler),
                    // and the anonymous handler will be executed in the
                    // next update pass.
                    syncCtx.Post((v) =>
                    {
                        WebView completedView = (WebView)v;

                        if (!exit)
                        {
                            return;
                        }

                        // Dispose the view.
                        completedView.Dispose();
                        savingSnapshots--;
                    }, view);
                }
            };

            // Call resize on the view. This will resize
            // and update the surface.
            view.Resize(view.Width, docHeight);
        }