コード例 #1
0
        /// <summary>
        /// Creates a disposable object that will lock the Queue for the duration of an event, disallowing any new tasks to be run beneath it.
        /// TODO: Is it enough to just use ExclusionLocker and be done with it? Probably.
        /// </summary>
        /// <param name="pipe"></param>
        /// <returns></returns>
        public static IDisposable BeginExclusiveOperation(this IEventPipe pipe)
        {
            //Prevent deadlock because we are already running exclusively.
            if (TaskScheduler.Current.Id == pipe.ExclusiveScheduler.Id)
            {
                return(Disposable.Empty);
            }
            void runShim(object state)
            {
                var casthadle = (Tuple <ManualResetEventSlim, CancellationToken>)state;

                casthadle.Item1.Set();
                casthadle.Item2.WaitHandle.WaitOne();
            }

            var src = new CancellationTokenSource();
            ManualResetEventSlim oneSlim = new ManualResetEventSlim();
            Tuple <ManualResetEventSlim, CancellationToken> thing = new Tuple <ManualResetEventSlim, CancellationToken>(oneSlim, src.Token);

            Task.Run(() =>
                     new Task(runShim, thing).RunSynchronously(pipe.ExclusiveScheduler), pipe.MainToken);
            //pipe.ExclusionLocker.Wait(()=> new TaskFactory(pipe.ExclusiveScheduler).StartNew(() =>
            //{
            //    oneSlim.Set();
            //    src.Token.WaitHandle.WaitOne();
            //}));
            oneSlim.Wait(pipe.MainToken);
            return(Disposable.Create(src, s =>
            {
                s.Cancel(false);
                s.Dispose();
            }));
        }
コード例 #2
0
        public EventPipeTests(ITestOutputHelper output)
        {
            outp = output;
            pipe = new EventPipe();
            var provCol = new ServiceCollection();

            provCol.AddScoped <List <int> >();
            testProv = provCol.BuildServiceProvider();
        }
コード例 #3
0
        public async void AsyncDisposeTest()
        {
            pipe = new EventPipe();
            var endThing = new TaskCompletionSource <bool>();
            var disposer = new RefCountDisposable(Disposable.Create(() => endThing.SetResult(true)));

            for (var i = 0; i < 100; i++)
            {
                pipe.ObserveFirst.Subscribe(new TestObserver(i, outp, "first", disposer.GetDisposable()));
                pipe.ObserveConcurrent.Subscribe(new TestObserver(i, outp, "reader", disposer.GetDisposable()));
                pipe.ObserveSynchronous.Subscribe(new TestObserver(i, outp, "writer", disposer.GetDisposable()));
            }
            disposer.Dispose();
            //var testTask = new List<Task>();
            var totalDisposer = new RefCountDisposable(Disposable.Create(() => pipe.Complete()));
            var rand          = new Random();

            Parallel.ForEach(Enumerable.Range(0, 99), async x =>
            {
                using (totalDisposer.GetDisposable())
                {
                    using (var scp = testProv.CreateScope())
                    {
                        var e = new MessageEvent
                        {
                            IgnoreThis  = false,
                            Services    = scp.ServiceProvider.CreateScope().ServiceProvider,
                            Scenario    = VersaCommsID.FromEnum(EVersaCommIDType.Scenario, 0),
                            Player      = new UnionType <VersaCommsID, IPlayer>(0),
                            Terminal    = new UnionType <VersaCommsID, IVersaWriter>(0),
                            FullMessage = x.ToString(),
                            Entity      = new UnionType <VersaCommsID, IEntity>(0),
                        };
                        await Task.Yield();
                        await pipe.ProcessEvent(e);
                    }
                }
            });

            //totalDisposer.Dispose();
            //scp.Dispose();
            //await Task.WhenAll(testTask);

            await Task.Delay(200);

            totalDisposer.Dispose();
            //await Task.Delay(200);
            await endThing.Task;
            //pipe.Dispose();
        }