在后台工作线程中睡觉的线程

本文关键字:线程 工作 后台 | 更新日期: 2023-09-27 17:54:57

我写了一个简单的应用程序,使用BackgroundWorker将100000行"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毫秒实际上使BackgroundWorker报告进度,但它非常慢。

我的问题是,是否有一种方法可以摆脱线程睡眠,但同时使BackgroundWorker正确报告进度?

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

在后台工作线程中睡觉的线程

我经常报告进度,而且没有理由多次报告相同的进度,浪费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;
    }

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

 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 ; 
}

SxProgress代码在此链接的最后一条消息中

还请注意,该类为并行进程提供了相同的简单接口,在计算机中创建与内核一样多的线程,并透明地将项目分配给不同的线程。

这将工作在WPF吗?遗憾的是没有:类包含一个窗体(winforms)与进度条,标签和停止按钮。

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

它可以通过从"添加引用"对话框中添加到WPF项目2中的引用来工作。网"选项卡),即。"System.Windows。窗体"answers"WindowsFormsIntegration"

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