Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有办法让WPF中的后台工作人员慢下来?_C#_Wpf - Fatal编程技术网

C# 有没有办法让WPF中的后台工作人员慢下来?

C# 有没有办法让WPF中的后台工作人员慢下来?,c#,wpf,C#,Wpf,在一些游戏中,有一个启动屏幕,可以从服务器下载内容。在你等待的时候,它可能会给你一些提示。我正在做类似的事情,只是加载速度非常快,但我希望它再等几秒钟 当用户第一次加载我的应用程序时,它有一个带有进度条的屏幕。目前,它检查服务器是否在线。如果是,它会说“已连接!”,但是,它会立即淡出我的控制。我想让它再等5秒钟,这样读者就可以阅读了。然后淡出控制 private void frmMain_Loaded(object sender, RoutedEventArgs e) {

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

当用户第一次加载我的应用程序时,它有一个带有进度条的屏幕。目前,它检查服务器是否在线。如果是,它会说“已连接!”,但是,它会立即淡出我的控制。我想让它再等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 
    }
private void M_bgWorker_DoWork(对象发送方,System.ComponentModel.DoWorkEventArgs e)
{
对于(int i=0;i<100;i++)
{ 
m_index++;
系统.线程.线程.睡眠(40);
m_bgWorker.报告进度(m_索引);
}
System.Threading.Thread.Sleep(3000);//等待3秒读取
}

成功了。进度条的动画制作相当流畅

您不应该在处理程序中进行淡出。该处理程序实际上应该只用于更新进度信息,如文本和百分比栏

淡出逻辑应移到单独的事件处理程序。在这里,您可以让线程在开始淡出控件之前休眠/等待一段时间。(在
Thread.Sleep()
上使用
async
/
wait
的优点是在等待时不阻塞UI线程,因此UI在等待时间流逝时仍保持响应。)

它还确保代码在最后被调用,而不是每次工作人员报告任何类型的进度时都被调用。它也更干净,因为它允许您通过检查
RunWorkedCompletedEventArgs
来处理不同的终止状态:

  • 如果设置了
    e.Error
    ,则工作线程中会发生异常
  • 如果
    e.Cancelled
    为true,则通过调用工作线程上的
    CancelAsync()
    来取消工作线程。(仅当
    WorkerSupportsCancellation
    设置为
    true
    时才可能,并且仅当处理程序中的代码实际检查取消标志时才有用)
  • 否则一切都会好起来的

旁注:


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

而不是加载的frmMain\u中的最后一行:

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

用于(int i=0;i注意到BackgroundWorker有一些附加事件,所以我尝试了这些事件。效果更好,是的!相关说明是,如果您使用.NET 4.5或更高版本,您可能希望使用
任务完成整个任务。运行
而不是
BackgroundWorker
。这似乎是一种更现代、更直接的方法这避免了所有不同事件处理程序的麻烦:我相信我尝试过Task,但由于它在单独的线程上运行,它无法访问控件,因为主线程控制了它。这有点麻烦,然后我遇到了BackgroundWorker。@Bob这就是Dispatcher的用途。Dispatcher.Invoke将运行func在UI线程上单击查看我发布的链接的第5点。要报告任务的进度,可以使用委托函数实例化
进度
对象,调用
报告()时会调用委托函数
方法。与后台工作程序相比,报告的对象可以按任何类型,而不仅仅是整数和字符串。使用
Thread.Sleep
几乎总是一个坏主意。
等待任务。延迟(TimeSpan.FromSeconds(1.0))
会更好。@Enigmatity:我试过了,但得到了这个错误:System.InvalidOperationException:“这个操作已经调用了OperationCompleted,以后的调用是非法的。”@Bob-听起来像是在重用一个
任务。延迟
。你能显示代码吗?@Bob-无论如何
睡眠
都不是答案。Sug对故意延迟的任务进行异步操作只是一种狂热的反应。异步并不是解决所有问题的答案。对于这个特定的用例,睡眠效果很好,因为在显示进度对话框时没有其他事情要做。如果有用户操作要做(不寻常),如果更改睡眠持续时间,用户界面在1秒或更短时间后仍会响应。