protected override void _bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            IsBusy = true;
            if (_spcItemInfoTable == null || _spcItemInfoTable.Rows.Count == 0)
            {
                return;
            }

            App.Current.Dispatcher.Invoke((Action) delegate // <--- HERE
            {
                _uniRptItems.Clear();
                _multiRptItems.Clear();
                _overviewItems.Clear();
                UnivariateContent.Clear();
                MultiVariateContent.Clear();
                OverviewTrend.Clear();
                ShowSeparator = false;
            });


            lock (_spcItemInfoTable)
            {
                string        connString = Database.DBQueryTool.GetConnString();
                StringBuilder query      = new StringBuilder();

                DataRow[]            spcItemRow = _spcItemInfoTable.Rows.Cast <DataRow>().ToArray();
                List <Model.IReport> rptItems   = new List <Model.IReport>();

                DataRow[] spcItemRow_uni = new DataRow[] { };
                DataRow[] spcItemRow_mul = new DataRow[] { };
                if (spcItemRow.Any(x => x.Field <string>("FLAG") == "T2"))
                {
                    spcItemRow_mul = spcItemRow.Where(x => x.Field <string>("FLAG") == "T2").ToArray();
                }
                if (spcItemRow.Any(x => x.Field <string>("FLAG") == "I"))
                {
                    spcItemRow_uni = spcItemRow.Where(x => x.Field <string>("FLAG") == "I").ToArray();
                }

                if (spcItemRow_mul.Length > 0 && spcItemRow_uni.Length > 0)
                {
                    ShowSeparator = true;
                }

                string start = string.Format("{0:yyyy-MM-dd} {1}", StartDate.Date, StartTimeValue);
                string end   = string.Format("{0:yyyy-MM-dd} {1}", EndDate.Date, EndTimeValue);

                string tmpDir = System.IO.Path.Combine(Environment.GetEnvironmentVariable("tmp"), "Minitab");
                try
                {
                    Array.ForEach(System.IO.Directory.GetFiles(tmpDir), System.IO.File.Delete); //刪除暫存區所有檔案
                }
                catch
                {
                }

                for (int i = 0; i < spcItemRow_mul.Length; i++)
                {
                    query.Clear();
                    Project.Commands.Delete();
                    Project.Worksheets.Delete();

                    DataRow dr = spcItemRow_mul[i];
                    Model.MultivariateReport rpt = new Model.MultivariateReport();
                    string[] item = dr["ITEM_LIST"].ToString().Split(',');
                    rpt.RawData = Database.DBQueryTool.GetPivotDataForMultivariateChart(_siteId, item, start, end);

                    //搜尋是否有參數
                    DataTable paraDetTable = null;
                    query.AppendLine("SELECT a.CHART_PARA_INDEX, b.FLAG, b.ROWNO, b.COLNO, b.VALUE, a.ITEM_LIST FROM CHART_PARAMETER a LEFT JOIN PARAMETER_DETAIL b");
                    query.AppendLine("ON a.CHART_PARA_INDEX = b.CHART_PARA_INDEX");
                    query.AppendFormat("WHERE a.ITEM_LIST='{0}'", dr["ITEM_LIST"].ToString());
                    paraDetTable   = Database.DBQueryTool.GetData(query.ToString(), Database.DBQueryTool.GetConnString());
                    rpt.Parameters = paraDetTable;

                    if (rpt.RawData != null && rpt.RawData.Rows.Count > 0)
                    {
                        rpt.Title = dr["TITLE"].ToString();
                        rpt.Flag  = dr["FLAG"].ToString();
                        try
                        {
                            rpt.Execute(_proj);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception("Minitab run time error\r\n" + ex.Message);
                        }

                        rptItems.Add(rpt);
                        App.Current.Dispatcher.Invoke((Action) delegate // <--- HERE
                        {
                            _multiRptItems.Add(rpt);
                        });
                    }
                    if (_bgWorker.CancellationPending)
                    {
                        Console.WriteLine("**We need to cancel the work...call _bgWorker_RunWorkerCompleted**");
                        return;
                    }
                }

                /*
                 * 針對單變量取得時間內所有資料 (不用處理SPC的工作)
                 *
                 */
                int iCnt = 0;
                iCnt = _spcItemInfoTable.Select("FLAG='I'").Count();
                if (iCnt > 1)//超過1組資料才要畫整體趨勢圖
                {
                    string[] item = spcItemRow_uni.Select(x => x.Field <string>("ITEM_LIST")).ToArray();
                    Model.OverlayTrendReport rpt = new Model.OverlayTrendReport();
                    string sTime = string.Format("{0:yyyy-MM-dd hh:mm:ss}", start);
                    string eTime = string.Format("{0:yyyy-MM-dd hh:mm:ss}", end);
                    rpt.RawData = Database.DBQueryTool.GetPivotDataForMultivariateChart(SITE_ID, item, sTime, eTime);

                    if (rpt.RawData != null && rpt.RawData.Rows.Count > 0)
                    {
                        rpt.Title = "整體趨勢圖";
                        try
                        {
                            rpt.Execute(Project);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception("Minitab run time error\r\n" + ex.Message);
                        }
                        rptItems.Add(rpt);
                        App.Current.Dispatcher.Invoke((Action) delegate // <--- HERE
                        {
                            _overviewItems.Add(rpt);
                        });
                    }
                }


                for (int i = 0; i < spcItemRow_uni.Length; i++)
                {
                    query.Clear();
                    Project.Commands.Delete();
                    Project.Worksheets.Delete();
                    DataRow dr = spcItemRow_uni[i];
                    Model.UnivariateReport rpt = new Model.UnivariateReport();
                    string[] item = dr["ITEM_LIST"].ToString().Split(',');
                    item = item.Select(x => "'" + x + "'").ToArray();
                    query.Clear();
                    //query.AppendLine("SELECT * FROM VW_FURNACEDATAINSPC");
                    //query.AppendFormat("WHERE FURN_ITEM_INDEX IN ({0}) ", string.Join(",", item));
                    //query.AppendFormat("AND RPT_DATETIME BETWEEN '{0}' AND '{1}'\r\n", start, end);
                    //query.AppendLine("ORDER BY RPT_DATETIME");

                    query.AppendLine(Database.DBQueryTool.GetSQLString_FurnacedataInSPC(SITE_ID, item, start, end));
                    query.AppendLine("SELECT * FROM @tmpfurnacedatainspc order by rpt_datetime");
                    rpt.RawData = Database.DBQueryTool.GetData(query.ToString(), connString);

                    if (rpt.RawData != null && rpt.RawData.Rows.Count > 0)
                    {
                        rpt.Title = dr["TITLE"].ToString();
                        rpt.Flag  = dr["FLAG"].ToString();
                        rpt.Execute(_proj);
                        rptItems.Add(rpt);
                        App.Current.Dispatcher.Invoke((Action) delegate // <--- HERE
                        {
                            _uniRptItems.Add(rpt);
                        });
                    }
                    if (_bgWorker.CancellationPending)
                    {
                        Console.WriteLine("**We need to cancel the work...call _bgWorker_RunWorkerCompleted**");
                        return;
                    }
                }
            }
        }
        protected override void _bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (_initialRun)
            {
                IsBusy = true;
            }
            if (_spcItemInfo == null || _spcItemInfo.Rows.Count == 0)
            {
                return;
            }


            lock (_spcItemInfo)
            {
                lock (_uniRptItems)
                {
                    lock (_multiRptItems)
                    {
                        string        connString = Database.DBQueryTool.GetConnString();
                        DateTime      end        = DateTime.Now;
                        DateTime      start      = end.AddHours(-24);
                        StringBuilder query      = new StringBuilder();

                        DataRow[]            spcItemRow = _spcItemInfo.Rows.Cast <DataRow>().ToArray();
                        List <Model.IReport> rptItems   = new List <Model.IReport>();

                        DataRow[] spcItemRow_uni = new DataRow[] { };
                        DataRow[] spcItemRow_mul = new DataRow[] { };
                        if (spcItemRow.Any(x => x.Field <string>("FLAG") == "T2"))
                        {
                            spcItemRow_mul = spcItemRow.Where(x => x.Field <string>("FLAG") == "T2").ToArray();
                        }
                        if (spcItemRow.Any(x => x.Field <string>("FLAG") == "I"))
                        {
                            spcItemRow_uni = spcItemRow.Where(x => x.Field <string>("FLAG") == "I").ToArray();
                        }

                        //Check whether the length of _uniRptItems is equal to spcItemRow_uni and
                        //the length of _multiRptItem is equal to spcItemRow_mul.
                        if (_multiRptItems.Count != spcItemRow_mul.Length || _uniRptItems.Count != spcItemRow_uni.Length)
                        {
                            return;                                                                                               //something have been modified by other thread.
                        }
                        string tmpDir = System.IO.Path.Combine(Environment.GetEnvironmentVariable("tmp"), "Minitab");
                        try
                        {
                            Array.ForEach(System.IO.Directory.GetFiles(tmpDir), System.IO.File.Delete); //刪除暫存區所有檔案
                        }
                        catch
                        {
                            //do nothing...反正這次刪不掉下次再刪
                        }


                        for (int i = 0; i < spcItemRow_mul.Length; i++)
                        {
                            if (_bgWorker.CancellationPending)
                            {
                                Console.WriteLine("**We need to cancel the work...call _bgWorker_RunWorkerCompleted**");
                                return;
                            }
                            query.Clear();
                            DataRow dr = spcItemRow_mul[i];
                            Model.MultivariateReport rpt = new Model.MultivariateReport();
                            string[] item  = dr["ITEM_LIST"].ToString().Split(',');
                            string   sTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", start);
                            string   eTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", end);
                            rpt.RawData = Database.DBQueryTool.GetPivotDataForMultivariateChart(_siteId, item, sTime, eTime);
                            if (_multiRptItems[i] != null && Database.DBQueryTool.CompareDataTableRow(_multiRptItems[i].RawData, rpt.RawData))
                            {
                                continue; //資料相等就不執行這次結果
                            }

                            //搜尋是否有參數
                            DataTable paraDetTable = null;
                            query.AppendLine("SELECT a.CHART_PARA_INDEX, b.FLAG, b.ROWNO, b.COLNO, b.VALUE, a.ITEM_LIST FROM CHART_PARAMETER a LEFT JOIN PARAMETER_DETAIL b");
                            query.AppendLine("ON a.CHART_PARA_INDEX = b.CHART_PARA_INDEX");
                            query.AppendFormat("WHERE a.ITEM_LIST='{0}'", dr["ITEM_LIST"].ToString());
                            paraDetTable   = Database.DBQueryTool.GetData(query.ToString(), Database.DBQueryTool.GetConnString());
                            rpt.Parameters = paraDetTable;

                            if (rpt.RawData != null && rpt.RawData.Rows.Count > 0)
                            {
                                rpt.Title = dr["TITLE"].ToString();
                                rpt.Flag  = dr["FLAG"].ToString();
                                try
                                {
                                    rpt.Execute(Project);
                                }
                                catch (Exception ex)
                                {
                                    //進到下一個迴圈
                                    continue;
                                    //throw new Exception("Minitab run time error\r\n" + ex.Message);
                                }
                                rptItems.Add(rpt);
                                App.Current.Dispatcher.Invoke((Action) delegate // <--- HERE
                                {
                                    _multiRptItems[i] = rpt;
                                });
                            }
                            if (_bgWorker.CancellationPending)
                            {
                                Console.WriteLine("**We need to cancel the work...call _bgWorker_RunWorkerCompleted**");
                                return;
                            }
                        }

                        /*
                         * 針對單變量取得時間內所有資料 (不用處理SPC的工作)
                         *
                         */
                        for (int i = 0; i < 1; i++)
                        {
                            string[] item = spcItemRow_uni.Select(x => x.Field <string>("ITEM_LIST")).ToArray();
                            Model.OverlayTrendReport rpt = new Model.OverlayTrendReport();
                            string sTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", start);
                            string eTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", end);
                            rpt.RawData = Database.DBQueryTool.GetPivotDataForMultivariateChart(SITE_ID, item, sTime, eTime);
                            if (rpt.RawData != null && rpt.RawData.Rows.Count > 0)
                            {
                                rpt.Title = "整體趨勢圖";
                                try
                                {
                                    rpt.Execute(Project);
                                }
                                catch (Exception ex)
                                {
                                    continue;
                                }
                                rptItems.Add(rpt);
                                App.Current.Dispatcher.Invoke((Action) delegate // <--- HERE
                                {
                                    _overviewItems[i] = rpt;
                                });
                            }
                        }

                        for (int i = 0; i < spcItemRow_uni.Length; i++)
                        {
                            if (_bgWorker.CancellationPending)
                            {
                                Console.WriteLine("**We need to cancel the work...call _bgWorker_RunWorkerCompleted**");
                                return;
                            }
                            query.Clear();
                            DataRow dr = spcItemRow_uni[i];
                            Model.UnivariateReport rpt = new Model.UnivariateReport();
                            string[] item = dr["ITEM_LIST"].ToString().Split(',');
                            item = item.Select(x => "'" + x + "'").ToArray();
                            query.Clear();
                            //query.AppendLine("SELECT * FROM VW_FURNACEDATAINSPC");
                            //query.AppendFormat("WHERE FURN_ITEM_INDEX IN ({0}) ", string.Join(",", item));
                            //string sTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", start);
                            //string eTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", end);
                            //query.AppendFormat("AND RPT_DATETIME BETWEEN '{0}' AND '{1}'\r\n", sTime, eTime);
                            //query.AppendLine("ORDER BY RPT_DATETIME");
                            string sTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", start);
                            string eTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", end);
                            query.AppendLine(Database.DBQueryTool.GetSQLString_FurnacedataInSPC(SITE_ID, item, sTime, eTime));
                            query.AppendLine("SELECT * FROM @tmpfurnacedatainspc order by rpt_datetime");

                            rpt.RawData = Database.DBQueryTool.GetData(query.ToString(), connString);
                            if (_uniRptItems[i] != null && Database.DBQueryTool.CompareDataTableRow(_uniRptItems[i].RawData, rpt.RawData))
                            {
                                continue; //資料相等就不執行這次結果
                            }

                            if (rpt.RawData != null && rpt.RawData.Rows.Count > 0)
                            {
                                rpt.Title = dr["TITLE"].ToString();
                                rpt.Flag  = dr["FLAG"].ToString();
                                try
                                {
                                    rpt.Execute(Project);
                                }
                                catch (Exception ex)
                                {
                                    continue;
                                    //throw new Exception("Minitab run time error\r\n" + ex.Message);
                                }
                                rptItems.Add(rpt);
                                App.Current.Dispatcher.Invoke((Action) delegate // <--- HERE
                                {
                                    _uniRptItems[i] = rpt;
                                });
                            }
                            if (_bgWorker.CancellationPending)
                            {
                                Console.WriteLine("**We need to cancel the work...call _bgWorker_RunWorkerCompleted**");
                                return;
                            }
                        }
                    }
                }
            }
        }