Looking for an example of a custom SynchronizationContext (Required for unit testing)

后端 未结 4 738
悲哀的现实
悲哀的现实 2020-12-03 01:50

I need a custom SynchronizationContext that:

  • Owns a single thread that runs \"Posts\" and \"Sends\" delegates
  • Does the send in the order they are sen
4条回答
  •  情话喂你
    2020-12-03 02:25

    This one was written by me some time ago, no issues with copyright, no guarantees either(the system didn't go into production):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Threading;
    
    namespace ManagedHelpers.Threads
    {
        public class STASynchronizationContext : SynchronizationContext, IDisposable
        {
            private readonly Dispatcher dispatcher;
            private object dispObj;
            private readonly Thread mainThread;
    
            public STASynchronizationContext()
            {
                mainThread = new Thread(MainThread) { Name = "STASynchronizationContextMainThread", IsBackground = false };
                mainThread.SetApartmentState(ApartmentState.STA);
                mainThread.Start();
    
                //wait to get the main thread's dispatcher
                while (Thread.VolatileRead(ref dispObj) == null)
                    Thread.Yield();
    
                dispatcher = dispObj as Dispatcher;
            }
    
            public override void Post(SendOrPostCallback d, object state)
            {
                dispatcher.BeginInvoke(d, new object[] { state });
            }
    
            public override void Send(SendOrPostCallback d, object state)
            {
                dispatcher.Invoke(d, new object[] { state });
            }
    
            private void MainThread(object param)
            {
                Thread.VolatileWrite(ref dispObj, Dispatcher.CurrentDispatcher);
                Console.WriteLine("Main Thread is setup ! Id = {0}", Thread.CurrentThread.ManagedThreadId);
                Dispatcher.Run();
            }
    
            public void Dispose()
            {
                if (!dispatcher.HasShutdownStarted && !dispatcher.HasShutdownFinished)
                    dispatcher.BeginInvokeShutdown(DispatcherPriority.Normal);
    
                GC.SuppressFinalize(this);
            }
    
            ~STASynchronizationContext()
            {
                Dispose();
            }
        }
    }
    

提交回复
热议问题