2015-05-03 59 views
0

我正在制作一个C#应用程序来监视SQL中的某些内容。我使用后台工作人员来获取SQL数据,然后根据数据构建一些图表。很基本。然而,这有一个令人沮丧的事情。在工作者中使用Thread.Sleep会完全锁定用户界面。没有加载gif,输入不注册,纳达。这对我来说是非常奇怪的行为,因为从我读到的背景工作者用例中,它应该运行在它自己的线程上,完全独立于UI。那么是什么给了?我可以用什么来代替这个?这是我的后台工作人员代码:C#appliction后台工作者 - Thread.Sleep停止用户界面

private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     if (CollectionCanceled) 
      return; 

     //Get data from SQL DB 
     var jobService = _serviceFactory.CreateJobService(); 
     var jobs = jobService.GetAllJobs(true); 
     backgroundWorker1.ReportProgress(0, jobs); 
    } 

    private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     var allJobs = e.UserState as IList<Job>; 
     if (allJobs == null || CollectionCanceled) 
      return; 

     //Build collection 
     Dictionary<string, Dictionary<string, int>> details = new Dictionary<string, Dictionary<string, int>>(); 
     foreach (var job in allJobs) 
     { 
      var overViewKey = job.State.ToString(); 
      var detailKey = string.Format("{0} ({1})", job.Name, job.Type); 

      if (!details.ContainsKey(overViewKey)) 
       details.Add(overViewKey, new Dictionary<string, int>()); 
      if (!details[overViewKey].ContainsKey(detailKey)) 
       details[overViewKey].Add(detailKey, 0); 

      details[overViewKey][detailKey]++; 
     } 

     //Build charts 
     Overview.Series.Clear(); 
     Detailed.Series.Clear(); 
     Overview.Series.Add("Jobs"); 
     Detailed.Series.Add("Jobs"); 

     foreach (var runniningOrEnqueued in details) 
     { 
      Overview.Series["Jobs"].Points.AddXY(runniningOrEnqueued.Key, runniningOrEnqueued.Value.Count); 
      foreach (var jobDetail in runniningOrEnqueued.Value) 
       Detailed.Series["Jobs"].Points.AddXY(jobDetail.Key, jobDetail.Value); 
     } 
     //Stop for however many secs the user specified 
     Thread.Sleep((int)TimeSpan.FromSeconds(WaitTimer).TotalMilliseconds); 
    } 

    private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if (!CollectionCanceled) 
     { 
      ExecuteBackGroundWork(); 
     } 
     else 
     { 
      CollectionCanceled = false; 
     } 
    } 

    private void ExecuteBackGroundWork() 
    { 
     backgroundWorker1.RunWorkerAsync(); 
    } 

回答

4

BackgroundWorker_ProgressChangedBackgroundWorker_ProgressChanged不会发生在工作线程上,它发生在UI线程上。只有BackgroundWorker_DoWork内发生的代码在工作线程上运行。

大多数你在里面ProgressChanged做的工作的(如果不是全部,我没有看到你的代码中的任何明确的UI交互,除非OverviewDetailed是UI成品的配件)应该里面DoWork的发生。

+0

BackgroundWorker_ProgressChanged在UI线程上发生的原因是,您可以更新UI中的控件。 –

+0

呵呵!我现在感到很傻。感谢您帮助应用程序n00b。一旦我能够,将会标记为答案。 – user2326106