using System;
using System.ComponentModel;
using System.Threading;

namespace Common.system
{
    /// <summary>
    /// 后台线程帮助类
    /// </summary>
    public class BackgroundWorkerHelper : IDisposable
    {
        private static BackgroundWorkerHelper backgroundWorkerHelper = null;

        public static BackgroundWorkerHelper GetInstance()
        {
            if (backgroundWorkerHelper == null)
            {
                backgroundWorkerHelper = new BackgroundWorkerHelper();
            }
            return backgroundWorkerHelper;
        }

        private BackgroundWorker backWorker = null;
        private Func<object> func = null;
        private Action<object> actionComplate = null;

        public BackgroundWorkerHelper()
        {
            backWorker = new BackgroundWorker();
            backWorker.DoWork += new DoWorkEventHandler(backWorker_DoWork);
            backWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backWorker_RunWorkerCompleted);
        }

        private void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            currentThread = null;

            if (e.Error != null)
            {
                throw e.Error;
            }
            if (actionComplate != null)
            {
                actionComplate(e.Result);
            }
        }

        private void backWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            currentThread = Thread.CurrentThread;

            if (func != null)
            {
                if (func != null)
                {
                    e.Result = func();
                }
            }
        }

        /// <summary>
        /// 启动异步线程
        /// </summary>
        /// <param name="func">在异步执行的方法</param>
        /// <param name="action">方法完成后</param>
        public void RunWorkerAsync(Func<object> func, Action<object> action)
        {
            if (!backWorker.IsBusy)
            {
                this.func = func;
                actionComplate = action;
                backWorker.RunWorkerAsync();
            }
        }

        private Thread currentThread = null;

        /// <summary>
        /// 强制中断
        /// </summary>
        public void Abort()
        {
            if (currentThread != null && backWorker.IsBusy)
            {
                currentThread.Abort();
                currentThread = null;

                backWorker.DoWork -= backWorker_DoWork;
                backWorker.RunWorkerCompleted -= backWorker_RunWorkerCompleted;
                backWorker.Dispose();

                backWorker = new BackgroundWorker();
                backWorker.DoWork += backWorker_DoWork;
                backWorker.RunWorkerCompleted += backWorker_RunWorkerCompleted;
                func = null;
                actionComplate = null;
            }
        }

        #region IDisposable 成员

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            actionComplate = null;
            func = null;
            backWorker.Dispose();
        }

        #endregion IDisposable 成员
    }
}
