예제 #1
0
    public static TaskScheduler GetSynchronizationContext()
    {
        TaskScheduler taskScheduler = null;

        try
        {
            taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        } catch {}
        if (taskScheduler == null)
        {
            try
            {
                taskScheduler = TaskScheduler.Current;
            } catch {}
        }
        if (taskScheduler == null)
        {
            try
            {
                var context = new CustomSynchronizationContext();
                SynchronizationContext.SetSynchronizationContext(context);
                taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
            } catch {}
        }
        return(taskScheduler);
    }
        public async Task DefaultWriterSchedulerRunsOnSynchronizationContext()
        {
            SynchronizationContext previous = SynchronizationContext.Current;
            var sc = new CustomSynchronizationContext();

            try
            {
                SynchronizationContext.SetSynchronizationContext(sc);

                using (var pool = new TestMemoryPool())
                {
                    var pipe = new Pipe(
                        new PipeOptions(
                            pool,
                            resumeWriterThreshold: 32,
                            pauseWriterThreshold: 64
                            ));

                    Func <Task> doWrite = async() =>
                    {
                        PipeWriter writableBuffer          = pipe.Writer.WriteEmpty(64);
                        ValueTask <FlushResult> flushAsync = writableBuffer.FlushAsync();

                        Assert.False(flushAsync.IsCompleted);

                        await flushAsync;

                        pipe.Writer.Complete();

                        Assert.Same(SynchronizationContext.Current, sc);
                    };

                    Task writing = doWrite();

                    // Don't run on our bogus sync context
                    ReadResult result = await pipe.Reader.ReadAsync().ConfigureAwait(false);

                    pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);

                    Assert.Equal(1, sc.Callbacks.Count);
                    sc.Callbacks[0].Item1(sc.Callbacks[0].Item2);

                    pipe.Reader.Complete();

                    // Don't run on our bogus sync context
                    await writing.ConfigureAwait(false);
                }
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(previous);
            }
        }
예제 #3
0
        public async Task FlushAsyncOnCompletedCapturesTheExecutionContextAndSyncContext(bool useSynchronizationContext)
        {
            var pipe = new Pipe(new PipeOptions(useSynchronizationContext: useSynchronizationContext, pauseWriterThreshold: 20, resumeWriterThreshold: 10));

            SynchronizationContext previous = SynchronizationContext.Current;
            var sc = new CustomSynchronizationContext();

            if (useSynchronizationContext)
            {
                SynchronizationContext.SetSynchronizationContext(sc);
            }

            try
            {
                AsyncLocal <int> val = new AsyncLocal <int>();
                var tcs = new TaskCompletionSource <int>();
                val.Value = 10;

                pipe.Writer.WriteEmpty(20);
                pipe.Writer.FlushAsync().GetAwaiter().OnCompleted(() =>
                {
                    tcs.TrySetResult(val.Value);
                });

                val.Value = 20;

                // Don't run any code on our fake sync context
                ReadResult result = await pipe.Reader.ReadAsync().ConfigureAwait(false);

                pipe.Reader.AdvanceTo(result.Buffer.End);

                if (useSynchronizationContext)
                {
                    Assert.Equal(1, sc.Callbacks.Count);
                    sc.Callbacks[0].Item1(sc.Callbacks[0].Item2);
                }

                int value = await tcs.Task.ConfigureAwait(false);

                Assert.Equal(10, value);
            }
            finally
            {
                if (useSynchronizationContext)
                {
                    SynchronizationContext.SetSynchronizationContext(previous);
                }

                pipe.Reader.Complete();
                pipe.Writer.Complete();
            }
        }
예제 #4
0
        public void SynchronizationContextSwitching()
        {
            var context = new CustomSynchronizationContext();

            SynchronizationContext.SetSynchronizationContext(context);

            var test   = _builder.BuildFrom(Method("AsyncVoidAssertSynchronizationContext"));
            var result = TestBuilder.RunTest(test, _testObject);

            Assert.AreSame(context, SynchronizationContext.Current);
            Assert.That(result.ResultState, Is.EqualTo(ResultState.Success), "Wrong result state");
            Assert.That(result.AssertCount, Is.EqualTo(0), "Wrong assertion count");
        }
        public void SynchronizationContextSwitching()
        {
            var context = new CustomSynchronizationContext();

            SynchronizationContext.SetSynchronizationContext(context);

            var method = _builder.BuildFrom(Method(f => f.Yield()));

            var result = method.Run(new NullListener(), TestFilter.Empty);

            Assert.AreSame(context, SynchronizationContext.Current);
            Assert.That(result.Executed, Is.True, "Was not executed");
            Assert.That(result.ResultState, Is.EqualTo(ResultState.Success), "Wrong result state");
            Assert.That(result.AssertCount, Is.EqualTo(0), "Wrong assertion count");
        }
예제 #6
0
        public async Task ReadAsyncOnCompletedCapturesTheExecutionContext(bool useSynchronizationContext)
        {
            var pipe = new Pipe(new PipeOptions(useSynchronizationContext: useSynchronizationContext));

            SynchronizationContext previous = SynchronizationContext.Current;
            var sc = new CustomSynchronizationContext();

            if (useSynchronizationContext)
            {
                SynchronizationContext.SetSynchronizationContext(sc);
            }

            try
            {
                AsyncLocal <int> val = new AsyncLocal <int>();
                var tcs = new TaskCompletionSource <int>();
                val.Value = 10;

                pipe.Reader.ReadAsync().GetAwaiter().OnCompleted(() =>
                {
                    tcs.TrySetResult(val.Value);
                });

                val.Value = 20;

                pipe.Writer.WriteEmpty(100);
                await pipe.Writer.FlushAsync();

                if (useSynchronizationContext)
                {
                    Assert.Equal(1, sc.Callbacks.Count);
                    sc.Callbacks[0].Item1(sc.Callbacks[0].Item2);
                }

                int value = await tcs.Task;
                Assert.Equal(10, value);
            }
            finally
            {
                if (useSynchronizationContext)
                {
                    SynchronizationContext.SetSynchronizationContext(previous);
                }

                pipe.Reader.Complete();
                pipe.Writer.Complete();
            }
        }
예제 #7
0
        /// <summary>
        /// Executes a task synchronously on the calling thread by installing a temporary synchronization context that queues continuations
        ///  </summary>
        public static void RunSync(Func <Task> task)
        {
            var currentContext = SynchronizationContext.Current;
            var customContext  = new CustomSynchronizationContext(task);

            try
            {
                SynchronizationContext.SetSynchronizationContext(customContext);

                customContext.Run();
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(currentContext);
            }
        }
예제 #8
0
        public static void RunSync(Func<Task> task)
        {
            var currentContext = SynchronizationContext.Current;
            var customContext = new CustomSynchronizationContext(task);

            try
            {
                SynchronizationContext.SetSynchronizationContext(customContext);

                customContext.Run();
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(currentContext);
            }
        }
        public async Task DefaultReaderSchedulerIgnoresSyncContextIfConfigureAwaitFalse()
        {
            // Get off the xunit sync context

            var previous = SynchronizationContext.Current;

            try
            {
                var sc = new CustomSynchronizationContext();
                SynchronizationContext.SetSynchronizationContext(sc);

                var pipe = new Pipe();

                Func <Task> doRead = async() =>
                {
                    ReadResult result = await pipe.Reader.ReadAsync().ConfigureAwait(false);

                    Assert.True(Thread.CurrentThread.IsThreadPoolThread);

                    pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);

                    pipe.Reader.Complete();
                };

                // This needs to run on the current SynchronizationContext
                Task reading = doRead();

                PipeWriter buffer = pipe.Writer;
                buffer.Write(Encoding.UTF8.GetBytes("Hello World"));

                // We don't want to run any code on our fake sync context
                await buffer.FlushAsync().ConfigureAwait(false);

                // Nothing posted to the sync context
                Assert.Equal(0, sc.Callbacks.Count);

                pipe.Writer.Complete();

                // We don't want to run any code on our fake sync context
                await reading.ConfigureAwait(false);
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(previous);
            }
        }
        public async Task DefaultReaderSchedulerRunsOnSynchronizationContext()
        {
            SynchronizationContext previous = SynchronizationContext.Current;
            var sc = new CustomSynchronizationContext();

            try
            {
                SynchronizationContext.SetSynchronizationContext(sc);

                var pipe = new Pipe();

                Func <Task> doRead = async() =>
                {
                    ReadResult result = await pipe.Reader.ReadAsync();

                    pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);

                    pipe.Reader.Complete();
                };

                // This needs to run on the current SynchronizationContext
                Task reading = doRead();

                PipeWriter buffer = pipe.Writer;
                buffer.Write(Encoding.UTF8.GetBytes("Hello World"));

                // Don't run code on our sync context (we just want to make sure the callbacks)
                // are scheduled on the sync context
                await buffer.FlushAsync().ConfigureAwait(false);

                Assert.Equal(1, sc.Callbacks.Count);
                sc.Callbacks[0].Item1(sc.Callbacks[0].Item2);

                pipe.Writer.Complete();

                // Don't run code on our sync context
                await reading.ConfigureAwait(false);
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(previous);
            }
        }
예제 #11
0
        public async Task UseSynchronizationContextFalseIgnoresSyncContextForReaderScheduler()
        {
            SynchronizationContext previous = SynchronizationContext.Current;
            var sc = new CustomSynchronizationContext();

            try
            {
                SynchronizationContext.SetSynchronizationContext(sc);

                var pipe = new Pipe(new PipeOptions(useSynchronizationContext: false));

                Func <Task> doRead = async() =>
                {
                    ReadResult result = await pipe.Reader.ReadAsync();

                    pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);

                    pipe.Reader.Complete();
                };

                // This needs to run on the current SynchronizationContext
                Task reading = doRead();

                PipeWriter buffer = pipe.Writer;
                buffer.Write("Hello World" u8.ToArray());

                // Don't run code on our sync context (we just want to make sure the callbacks)
                // are scheduled on the sync context
                await buffer.FlushAsync().ConfigureAwait(false);

                // Nothing posted to the sync context
                Assert.Equal(0, sc.Callbacks.Count);

                pipe.Writer.Complete();

                // Don't run code on our sync context
                await reading.ConfigureAwait(false);
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(previous);
            }
        }
예제 #12
0
        public void ContextDisposable1_Test()
        {
            // arrange
            bool isDisposedOnContext = false;
            var  context             = new CustomSynchronizationContext();

            var innerDisposable = Disposable.Create(() =>
                                                    isDisposedOnContext = (SynchronizationContext.Current == context));
            var disp = new ContextDisposable(context, innerDisposable);

            // act
            disp.Dispose();
            // just blocking until context execution completion
            context.Wait();

            // verify
            Assert.IsNull(SynchronizationContext.Current);
            Assert.IsTrue(disp.IsDisposed);
            Assert.IsTrue(isDisposedOnContext);
        }
예제 #13
0
        private static void Launch(UserCodeExceptionCatchMode exceptionMode)
        {
            EngineSetting.UserCodeExceptionCatchMode = exceptionMode;

            try {
                Elffy.Diagnostics.DevEnv.Run();
                Engine.Run();
                var screen = CreateScreen();
                screen.Initialized += OnScreenInitialized;
                CustomSynchronizationContext.Install(out var syncContextReciever);
                screen.Activate();
                while (Engine.HandleOnce())
                {
                    syncContextReciever?.DoAll();
                }
            }
            finally {
                CustomSynchronizationContext.Restore();
                Engine.Stop();
                Elffy.Diagnostics.DevEnv.Stop();
            }
        }
예제 #14
0
        public async Task DefaultReaderSchedulerRunsOnSynchronizationContext()
        {
            SynchronizationContext previous = SynchronizationContext.Current;
            var sc = new CustomSynchronizationContext();

            try
            {
                SynchronizationContext.SetSynchronizationContext(sc);

                var pipe = new Pipe();

                Func <Task> doRead = async() =>
                {
                    ReadResult result = await pipe.Reader.ReadAsync();

                    pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);

                    pipe.Reader.Complete();
                };

                Task reading = doRead();

                PipeWriter buffer = pipe.Writer;
                buffer.Write(Encoding.UTF8.GetBytes("Hello World"));
                await buffer.FlushAsync();

                Assert.Equal(1, sc.Callbacks.Count);
                sc.Callbacks[0].Item1(sc.Callbacks[0].Item2);

                pipe.Writer.Complete();

                await reading;
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(previous);
            }
        }
예제 #15
0
        public void SynchronizationContextSwitching()
        {
            var context = new CustomSynchronizationContext();

            SynchronizationContext.SetSynchronizationContext(context);

            var test = _builder.BuildFrom(Method("AsyncVoidAssertSynchronizationContext"));
            var result = TestBuilder.RunTest(test, _testObject);

            Assert.AreSame(context, SynchronizationContext.Current);
            Assert.That(result.ResultState, Is.EqualTo(ResultState.Success), "Wrong result state");
            Assert.That(result.AssertCount, Is.EqualTo(0), "Wrong assertion count");
        }
예제 #16
0
		public void SynchronizationContextSwitching()
		{
			var context = new CustomSynchronizationContext();

			SynchronizationContext.SetSynchronizationContext(context);

			var method = _builder.BuildFrom(Method(f => f.Yield()));

			var result = method.Run(new NullListener(), TestFilter.Empty);

			Assert.AreSame(context, SynchronizationContext.Current);
			Assert.That(result.Executed, Is.True, "Was not executed");
			Assert.That(result.ResultState, Is.EqualTo(ResultState.Success), "Wrong result state");
			Assert.That(result.AssertCount, Is.EqualTo(0), "Wrong assertion count");
		}