public void Start()
        {
            lock (_lockObject)
            {
                if (_started)
                {
                    return;
                }
                _started = true;

                HostingEnvironment.RegisterObject(this);

                // https://github.com/HangfireIO/Hangfire/blob/master/src/Hangfire.SqlServer/SqlServerStorageOptions.cs
                var options = new SqlServerStorageOptions
                {
                    PrepareSchemaIfNecessary = true, // 刪除相關資料表,當重新啟動後也會自動建立相關資料表

                    // 每15秒,查詢是否有需要執行的Job
                    // You can adjust the polling interval, but, as always, lower intervals can harm your SQL Server, and higher interval produce too much latency, so be careful.
                    QueuePollInterval = TimeSpan.FromSeconds(15), // Default value

                    // 不知道怎麼使用
                    // InvisibilityTimeout = TimeSpan.FromMinutes(30) // default value
                };

                GlobalConfiguration.Configuration
                // .UseSqlServerStorage("ApplicationDbContext") // 使用下面的方式,要不然使用別的config,這裡的連線資訊也要跟著調整
                .UseSqlServerStorage(new ApplicationDbContext().Database.Connection.ConnectionString, options);

                //GlobalConfiguration.Configuration.UseLogProvider(new HangfireLogProvider()); // 暫時先關閉,除非要偵錯 Hangfire

                // http://docs.hangfire.io/en/latest/background-methods/using-ioc-containers.html
                var container    = UnityConfig.GetConfiguredBackgroundContainer() as UnityContainer;
                var jobActivator = new MyUnityJobActivator(container);
                GlobalConfiguration.Configuration.UseActivator(jobActivator);

                // http://docs.hangfire.io/en/latest/background-processing/dealing-with-exceptions.html
                // 預設重試次數
                GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute {
                    Attempts = 0
                });                                                                         // 20160701 Norman, 失敗了不要重試,如果失敗,每固定時間系統自行決定需要發送的簡訊,重發的簡訊,或者是 GetDeliveryReport,因此不需要重送。
                // 手動指定重試次數
                // [AutomaticRetry(Attempts = 0)]

                GlobalJobFilters.Filters.Add(new ChildContainerPerJobFilterAttribute(jobActivator));

                RecurringJob.AddOrUpdate <EfSmsBackgroundJob>("CheckMonthlyAllotPoint", x => x.CheckMonthlyAllotPoint(), Cron.Minutely);
                RecurringJob.AddOrUpdate <EfSmsBackgroundJob>("SendSMS", x => x.SendSMS(), Cron.Minutely);
                for (var i = 0; i < 6; i++) // every 10 minute
                {
                    int min = i * 10;

                    RecurringJob.AddOrUpdate <EfSmsBackgroundJob>("RetrySMS" + min.ToString("0:00"), x => x.RetrySMS(), Cron.Hourly(min));
                    RecurringJob.AddOrUpdate <EfSmsBackgroundJob>("GetDeliveryReport" + min.ToString("0:00"), x => x.GetDeliveryReport(), Cron.Hourly(min));
                    RecurringJob.AddOrUpdate <EfSmsBackgroundJob>("HandleDeliveryReportTimeout" + min.ToString("0:00"), x => x.HandleDeliveryReportTimeout(), Cron.Hourly(min));
                }

                RecurringJob.AddOrUpdate <EfSmsBackgroundJob>("HouseKeeping", x => x.HouseKeeping(), Cron.Minutely);

                // 建立Background JobSserver 來處理 Job

                // http://docs.hangfire.io/en/latest/background-processing/configuring-queues.html
                var backgroundJobServerOptions = new BackgroundJobServerOptions
                {
                    Queues = new[] {
                        EFunTech.Sms.Portal.EfSmsBackgroundJob.QueueLevel.Critical,
                        EFunTech.Sms.Portal.EfSmsBackgroundJob.QueueLevel.High,
                        EFunTech.Sms.Portal.EfSmsBackgroundJob.QueueLevel.Medium,
                        EFunTech.Sms.Portal.EfSmsBackgroundJob.QueueLevel.Low
                    },
                    //WorkerCount = Environment.ProcessorCount * 5, // This is the default value
                    WorkerCount = Environment.ProcessorCount * 50, // (1000 個 GetDeliveryReport Request) * (2.5 秒 - 每個 Request 花費時間) / 60 (每分鐘幾秒)  = 41.66666 (分鐘才能完成工作)
                };

                /*
                 * public class QueueLevel
                 * {
                 * public const string Critical = "critical";
                 * public const string High = "high";
                 * public const string Medium = "medium";
                 * public const string Low = "low";
                 * }
                 */
                _backgroundJobServer = new BackgroundJobServer(backgroundJobServerOptions);
            }
        }
 public ChildContainerPerJobFilterAttribute(MyUnityJobActivator unityJobActivator)
 {
     UnityJobActivator = unityJobActivator;
 }