public void DisposeTest()
        {
            OcDispatcher         dispatcher = new OcDispatcher();
            ManualResetEventSlim mre        = new ManualResetEventSlim(false);
            bool invoked1 = false;
            bool invoked2 = false;
            bool freezed  = false;
            InvocationResult <bool> invocationResult  = null;
            InvocationResult <bool> invocationResult1 = null;

            dispatcher.InvokeAsync(() =>
            {
                dispatcher.InvokeAsync(() =>
                {
                    freezed = true;
                    mre.Wait();
                });


                invocationResult = dispatcher.Invoke(() => invoked1 = true);
            });

            Thread thread = new Thread(
                () =>
            {
                while (!freezed)
                {
                }

                invocationResult1 = dispatcher.Invoke(() => invoked2 = true);
            });

            thread.Start();

            ManualResetEventSlim mreDisposed = new ManualResetEventSlim(false);

            dispatcher.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == nameof(OcDispatcher.Status) &&
                    dispatcher.Status == OcDispatcherStatus.Disposed)
                {
                    mreDisposed.Set();
                }
            };

            while (dispatcher.GetQueueCount() != 2)
            {
            }

            dispatcher.Dispose();
            mre.Set();
            thread.Join();
            mreDisposed.Wait();

            Assert.IsFalse(invoked1);
            Assert.IsFalse(invoked2);
            Assert.AreEqual(invocationResult.Invocation.Status, InvocationStatus.Canceled);
            Assert.AreEqual(invocationResult1.Invocation.Status, InvocationStatus.Canceled);
        }
        private void App_OnExit(object sender, ExitEventArgs e)
        {
            OcDispatcher backgroundOcDispatcher = _container.GetInstance <OcDispatcher>();

            _container.Dispose();

            while (!RecurringAction.AllInstancesIsDisposed)
            {
                Dispatcher.Invoke(() => { }, DispatcherPriority.Background);
            }

            while (backgroundOcDispatcher.GetQueueCount() > 0)
            {
                Thread.Sleep(10);
            }

            _containerOcDispatcher.Dispose();
        }
        public void TestSetThreadProperites()
        {
            OcConfiguration.SaveInstantiationStackTrace = true;
            OcDispatcher dispatcher = new OcDispatcher(2);

            Assert.AreEqual(dispatcher.GetQueueCount(0), 0);
            Assert.AreEqual(dispatcher.GetQueueCount(), 0);
            Assert.IsTrue(dispatcher.InstantiationStackTrace != null);
            ApartmentState apartmentState = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ?  ApartmentState.Unknown : ApartmentState.MTA;

            Assert.AreEqual(dispatcher.NewInvocationBehaviour, NewInvocationBehaviour.Accept);
            Assert.AreEqual(dispatcher.Status, OcDispatcherStatus.ExecutingOrWait);
            Assert.AreEqual(dispatcher.GetThreadApartmentState(), apartmentState);
            Assert.AreEqual(dispatcher.PrioritiesNumber, 2);
            CultureInfo culture = CultureInfo.GetCultureInfo("ru-RU");

            dispatcher.ThreadIsBackground = true;
            dispatcher.ThreadName         = "ThreadName";
            Assert.AreEqual(dispatcher.ToString(), "(ObservableComputations.OcDispatcher (Thread.Name = 'ThreadName'))");
            dispatcher.ThreadPriority = ThreadPriority.Highest;
            int managedThreadId = dispatcher.ManagedThreadId;

            Assert.IsTrue(dispatcher.ThreadState == (ThreadState.WaitSleepJoin | ThreadState.Background) || dispatcher.ThreadState == (ThreadState.Running | ThreadState.Background));

            Assert.AreEqual(dispatcher.ThreadIsBackground, true);
            Assert.AreEqual(dispatcher.ThreadName, "ThreadName");
            Assert.AreEqual(dispatcher.ThreadPriority, ThreadPriority.Highest);
            Assert.AreEqual(dispatcher.ThreadIsAlive, true);
            Assert.AreEqual(dispatcher.ManagedThreadId, managedThreadId);
            Assert.AreEqual(dispatcher.GetThreadApartmentState(), apartmentState);


            dispatcher.Invoke(() =>
            {
                dispatcher.ThreadCurrentCulture   = culture;
                dispatcher.ThreadCurrentUICulture = culture;
                Assert.AreEqual(Thread.CurrentThread.CurrentCulture, culture);
                Assert.AreEqual(Thread.CurrentThread.CurrentUICulture, culture);
                Assert.AreEqual(dispatcher.ThreadCurrentCulture, culture);
                Assert.AreEqual(dispatcher.ThreadCurrentUICulture, culture);
                Assert.AreEqual(Thread.CurrentThread.IsBackground, true);
                Assert.AreEqual(Thread.CurrentThread.Name, "ThreadName");
                Assert.AreEqual(Thread.CurrentThread.Priority, ThreadPriority.Highest);
                Assert.AreEqual(Thread.CurrentThread.IsAlive, true);
                Assert.AreEqual(dispatcher.ThreadExecutionContext, Thread.CurrentThread.ExecutionContext);
                Assert.AreEqual(Thread.CurrentThread.ManagedThreadId, managedThreadId);
                Assert.AreEqual(Thread.CurrentThread.GetApartmentState(), apartmentState);
            });

            ManualResetEventSlim mreDisposed = new ManualResetEventSlim(false);

            dispatcher.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == nameof(OcDispatcher.Status) &&
                    dispatcher.Status == OcDispatcherStatus.Disposed)
                {
                    mreDisposed.Set();
                }
            };

            dispatcher.Dispose();
            Assert.AreEqual(dispatcher.NewInvocationBehaviour, NewInvocationBehaviour.Cancel);

            Exception exception = null;

            try
            {
                dispatcher.NewInvocationBehaviour = NewInvocationBehaviour.Accept;
            }
            catch (Exception e)
            {
                exception = e;
            }

            Assert.IsNotNull(exception);

            mreDisposed.Wait();
            Assert.AreEqual(dispatcher.Status, OcDispatcherStatus.Disposed);
        }