网站后台调用winform MessageLoopApartment

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AnfleCrawler.Common
{
    /// <summary>
    /// more info: http://*.com/a/21808747/1768303
    /// </summary>
    public class MessageLoopApartment : IDisposable
    {
        /// <summary>
        /// the STA thread
        /// </summary>
        private Thread _thread;
        private TaskScheduler _taskScheduler;

        /// <summary>
        /// the STA thread‘s task scheduler
        /// </summary>
        public TaskScheduler TaskScheduler
        {
            get { return _taskScheduler; }
        }

        /// <summary>
        /// MessageLoopApartment constructor
        /// </summary>
        public MessageLoopApartment()
        {
            var tcs = new TaskCompletionSource<TaskScheduler>();
            // start an STA thread and gets a task scheduler
            _thread = new Thread(startArg =>
            {
                EventHandler idleHandler = null;
                idleHandler = (s, e) =>
                {
                    // handle Application.Idle just once
                    Application.Idle -= idleHandler;
                    // return the task scheduler
                    tcs.SetResult(TaskScheduler.FromCurrentSynchronizationContext());
                };

                // handle Application.Idle just once
                // to make sure we‘re inside the message loop
                // and SynchronizationContext has been correctly installed
                Application.Idle += idleHandler;
                Application.Run();
            });
            _thread.IsBackground = true;
            _thread.SetApartmentState(ApartmentState.STA);
            _thread.Start();
            _taskScheduler = tcs.Task.Result;
        }
        /// <summary>
        /// Shutdown the STA thread
        /// </summary>
        public void Dispose()
        {
            if (_taskScheduler != null)
            {
                var taskScheduler = _taskScheduler;
                _taskScheduler = null;

                // execute Application.ExitThread() on the STA thread
                Task.Factory.StartNew(Application.ExitThread, CancellationToken.None, TaskCreationOptions.None, taskScheduler).Wait();
                _thread.Join();
                _thread = null;
            }
        }

        public void Invoke(Action func)
        {
            Task.Factory.StartNew(func, CancellationToken.None, TaskCreationOptions.None, _taskScheduler).Wait();
        }
        public TResult Invoke<TResult>(Func<TResult> func)
        {
            return Task.Factory.StartNew(func, CancellationToken.None, TaskCreationOptions.None, _taskScheduler).Result;
        }

        internal void Invoke(Action<object> func, object state)
        {
            Task.Factory.StartNew(func, state, CancellationToken.None, TaskCreationOptions.None, _taskScheduler);
        }
    }
}

 

网站后台调用winform MessageLoopApartment

上一篇:全程图解 手把手教您开启windows终端服务


下一篇:底层并发APIs_源自objc.io