睡觉在BackgroundWorker的螺纹

时间:2015-06-10 19:46:24

标签: c# wpf multithreading backgroundworker thread-sleep

我写了一个简单的应用程序,增加了10万行" Hello World"到使用BackgroundWorker的列表。

以下是我的后台工作人员在一个单独的线程中所做的工作的代码:

    private void BgWorkerOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
    {
        int min = 0;

        foreach (var hw in hwList)
        {
            //new ManualResetEvent(false).WaitOne(1);
            Thread.Sleep(1);
            int progress = Convert.ToInt32((Double)min / hwList.Count * 100);
            min++;
            bgWorker.ReportProgress(progress);
        }
    }

    // Updating the progress
    private void BgWorkerOnProgressChanged(object sender, ProgressChangedEventArgs progressChangedEventArgs)
    {
        ProgressBar.Value = progressChangedEventArgs.ProgressPercentage;
    }

一切正常,但如果我删除 Thread.Sleep(1) BackgroundWorker 不再报告进度。 (我想它需要一些时间)。将线程暂停1 ms实际上会使 BackgroundWorker 报告进度,但速度非常慢。

我的问题是,有没有办法摆脱线程休眠但同时让 BackgroundWorker 正确报告进度?

根据我的理解,暂停 BackgroundWorker 是不可避免的,因为线程需要一些时间来执行任务,但我想知道是否有解决方法。

3 个答案:

答案 0 :(得分:2)

我遇到的问题是我经常报告进度,而且没有理由报告相同的进度这么多次浪费cpu周期。

 private void BgWorkerOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
    {
        int min = 0;
        int oldProgress = 0;
        foreach (var hw in hwList)
        {
            // new ManualResetEvent(false).WaitOne(1);
            // Thread.Sleep(1);
            int progress = Convert.ToInt32((Double)min / hwList.Count * 100);
            min++;

            // Only report progress when it changes
            if(progress != oldProgress){
                 bgWorker.ReportProgress(progress);
                 oldProgress = progress;
            }
        }
    }

    // Updating the progress
    private void BgWorkerOnProgressChanged(object sender, ProgressChangedEventArgs progressChangedEventArgs)
    {
        ProgressBar.Value = progressChangedEventArgs.ProgressPercentage;
    }

答案 1 :(得分:0)

我开发了一个名为SxProgress的类,而不是BackgroundWorker,它有一个非常简单的接口,您可以通过以下方式使用它:

 int DesiredLinesCount = 100000 ;
 List<string> Lines=new List<string>() ;
 object[] UserObjects = new object[] { Lines } ; 
 SxProgress.Execute("Building lines",DesiredLinesCount,true,false,
                    BuildLines_ExecInThread,UserObjects)) ;

 private bool BuildLines_ExecInThread(int ItemIndex,object[] UserObjects)
{
  // some sleep to slow down the process (demonstration purpose only)
  // if (ItemIndex % 10 ==0) System.Threading.Thread.Sleep(1) ; 
  List<string> Lines= (List<String>)UserObjects[0] ;
  Lines.Add("Hello world") ; 
  return true ; 
}

The SxProgress code is in the last message of this link

还要注意,该类为并行进程提供了相同的简单接口,可以创建与计算机中的核心一样多的线程,并将项目透明地分发到不同的线程。

答案 2 :(得分:0)

  

这对WPF有用吗?   很遗憾没有:该课程包含带有进度条,标签和停止按钮的表单(winforms)。

可能的解决方案我从未尝试过。

它可以通过从“添加引用”对话框表单(在“.NET”选项卡中)添加到WPF项目2引用,即。 “System.Windows.forms”和“WindowsFormsIntegration”。

然后,在源代码中,添加“using System.Windows.Forms;” 和“使用System.Windows.Forms.Integration;”