有没有办法减慢WPF中的BackgroundWorker?

时间:2018-04-08 22:51:32

标签: c# wpf

在某些游戏中,有一个从服务器下载内容的启动画面。在你等待的时候,它可能会提供一些提示。我正在做类似的事情,只是加载发生得非常快,但我希望它再等几秒钟。

当用户首次加载我的应用程序时,它有一个带有进度条的屏幕。目前,它会检查服务器是否在线。如果是,它说“连接!”但是,它会立即淡化我的控件。我希望它等待大约5秒钟,以便读者可以阅读它。然后淡出控件。

    private void frmMain_Loaded(object sender, RoutedEventArgs e)
    {  
        // Start background worker
        m_bgWorker = new System.ComponentModel.BackgroundWorker();
        m_bgWorker.ProgressChanged += M_bgWorker_ProgressChanged;
        m_bgWorker.WorkerReportsProgress = true;
        m_bgWorker.RunWorkerAsync(); 
        m_bgWorker.ReportProgress(100); 
    } 


    private void M_bgWorker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
    {
        progConnect.Value = 0; 

        if (SystemBO.IsOnline())
        {
            lblConnection.Content = "Connected!"; 
        }

        progConnect.Value = e.ProgressPercentage;

        // TODO: Wait 5 seconds here...

        // Fade out controls
        lblTitle.BeginAnimation(Label.OpacityProperty, doubleAnimation);
        progConnect.BeginAnimation(Label.OpacityProperty, doubleAnimation);
        lblConnection.BeginAnimation(Label.OpacityProperty, doubleAnimation);
    }

注意:

  • 我尝试了System.Sleep(),但这没有任何区别。我理解为什么。这个想法是一样的:我希望后台工作者在完成之前睡5秒钟。

解决方案:

我添加了一些事件:DoWork和RunWorkerCompleted。

然后我添加了这段代码:

    private void M_bgWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        for (int i = 0; i < 100; i++)
        { 
                m_index++;
                System.Threading.Thread.Sleep(40);
                m_bgWorker.ReportProgress(m_index);
        }

        System.Threading.Thread.Sleep(3000);  // wait 3 seconds to read 
    }

有效。进度条动画非常流畅。

2 个答案:

答案 0 :(得分:0)

你不应该在ProgressChanged处理程序中执行淡出操作。该处理程序实际上只应用于更新文本和百分比栏等进度信息。

您的淡出逻辑应移至单独的RunWorkedCompleted事件处理程序。在开始淡出控件之前,您可以让线程休眠/等待计划任务一段时间。 (在此async上使用await / Thread.Sleep()具有在等待时不阻止UI线程的优势,因此在等待时间过后,UI仍然保持响应。)

它还确保在最后调用代码,而不是每次工作人员报告任何类型的进度时。而且它也更清晰,因为它允许您通过检查RunWorkedCompletedEventArgs

来处理不同的终止状态
  • 如果设置了e.Error,则工作线程中发生异常。
  • 如果e.Cancelled为真,则通过调用worker上的CancelAsync()来取消工作线程。 (仅当WorkerSupportsCancellation设置为true时才有效,仅在DoWork处理程序中的代码实际检查取消标记时才有用
  • 否则一切顺利。

旁注:

我假设你的代码不是一个完整的例子,因为你没有为DoWork事件分配实际的处理程序。所以现在它不会做任何事情。从主线程调用ReportProgress()也是错误的。该方法旨在从DoWork事件处理方法中调用,以便让异步线程将状态更新报告回UI,因为这些事件是在主线程上处理的。

答案 1 :(得分:-2)

而不是frmMain_Loaded中的最后一行:

m_bgWorker.ReportProgress(100); 

我会使用Sleep()进行for循环,以模拟一些额外的处理:

for (int i=0; i<=100; i+=10)
{
    if (SystemBO.IsOnline())
        i = 100;
    Sleep(1000);
    m_bgWorker.ReportProgress(i);
}