C# WPF应用程序不确定进度条不';不显示,但进程正在后台运行
当我让进程开始工作时,我在尝试添加ProgressBar以向用户提供进程没有崩溃的线索时,可能遇到了线程问题。既然这已经足够了,一个无限的进度条对我来说很好C# WPF应用程序不确定进度条不';不显示,但进程正在后台运行,c#,wpf,user-interface,async-await,C#,Wpf,User Interface,Async Await,当我让进程开始工作时,我在尝试添加ProgressBar以向用户提供进程没有崩溃的线索时,可能遇到了线程问题。既然这已经足够了,一个无限的进度条对我来说很好 <ProgressBar x:Name="ProcessProgress" Minimum="0" Maximum="100" Visibility="Hidden" IsIndeterminate="False" Width="305" Height="20" Margin="240,214,248,10"></Pro
<ProgressBar x:Name="ProcessProgress" Minimum="0" Maximum="100" Visibility="Hidden" IsIndeterminate="False" Width="305" Height="20" Margin="240,214,248,10"></ProgressBar>
它只是运行整个过程,我的酒吧没有出现
如何在该过程中生成进度条?问题是您的所有代码都在UI线程中运行。在整个过程完成之前,UI没有机会进行自我更新 您可以使用
Task.Run()
在后台运行繁重的作业,而不会阻塞UI。您可以使用await
关键字等待任务完成,而不阻塞UI。任务完成后,您将返回UI线程,可以在其中再次修改UI
此事件处理程序的快速修复程序如下:
private async void Start_Click(object sender, RoutedEventArgs e)
{
ProcessProgress.IsIndeterminate = true;
ProcessProgress.Visibility = Visibility.Visible;
...
await Task.Run(()=>
{
//process starts here
var fP = new FileProcessor();
...
});
//We are back in the UI thread, we can modify the UI
ProcessProgress.IsIndeterminate = false;
ProcessProgress.Value = ProcessProgress.Maximum;
}
无需使用Invoke
返回UI线程,这就是wait
本身的工作
关于异步void
的说明。它只适用于事件处理程序或类似的方法。您不能等待async void
方法,这意味着您甚至不能在出现问题时获得任何异常。不返回任何内容的异步方法应具有异步任务
签名
如果要报告进度,可以使用所解释的接口和类。Progress类将在创建它的线程上调用回调或引发事件。有效负载可以是任何类别,而不仅仅是百分比
最好将报告代码移动到单独的方法中,以保持按钮处理程序干净。代码可以如下所示:
//The progress class
class FileProgress
{
public string FileName{get;set;}
public int Progress{get;set;}
public string Message{get;set;}
public FileProgress(string fileName,int progress,string message)
{
FileName=filename;
Progress=progress;
Message=message;
}
}
//In the form itself
private void ReportStart()
{
ProcessProgress.IsIndeterminate = true;
ProcessProgress.Visibility = Visibility.Visible;
}
private void ReportEnd()
{
ProcessProgress.IsIndeterminate = false;
ProcessProgress.Value = ProcessProgress.Maximum;
}
private void ReportProgress(FileProgress progress)
{
ProcessProgress.Value =progress.Progress;
PanelStatus.Text = $"Working on {progress.FileName} : {progress.Message}";
}
private async void Start_Click(object sender, RoutedEventArgs e)
{
ReportStart();
IProgress<FileProgress> progress=new Progress<FileProgress>(ReportProgress);
...
await Task.Run(()=>
{
//process starts here
var fP = new FileProcessor();
foreach(var file in someFiles)
{
progress.Report(new FileProgress(file,0,"Starting");
//Do some processing
progress.Report(new FileProgress(file,100,"Finished");
}
...
});
//We are back in the UI thread, we can modify the UI
ReportEnd();
}
事件处理程序现在可以如下所示:
//The progress class
class FileProgress
{
public string FileName{get;set;}
public int Progress{get;set;}
public string Message{get;set;}
public FileProgress(string fileName,int progress,string message)
{
FileName=filename;
Progress=progress;
Message=message;
}
}
//In the form itself
private void ReportStart()
{
ProcessProgress.IsIndeterminate = true;
ProcessProgress.Visibility = Visibility.Visible;
}
private void ReportEnd()
{
ProcessProgress.IsIndeterminate = false;
ProcessProgress.Value = ProcessProgress.Maximum;
}
private void ReportProgress(FileProgress progress)
{
ProcessProgress.Value =progress.Progress;
PanelStatus.Text = $"Working on {progress.FileName} : {progress.Message}";
}
private async void Start_Click(object sender, RoutedEventArgs e)
{
ReportStart();
IProgress<FileProgress> progress=new Progress<FileProgress>(ReportProgress);
...
await Task.Run(()=>
{
//process starts here
var fP = new FileProcessor();
foreach(var file in someFiles)
{
progress.Report(new FileProgress(file,0,"Starting");
//Do some processing
progress.Report(new FileProgress(file,100,"Finished");
}
...
});
//We are back in the UI thread, we can modify the UI
ReportEnd();
}
private async void Start\u单击(对象发送方,路由目标)
{
ReportStart();
i进度=新进度(报告进度);
...
等待任务。运行(()=>
{
//过程从这里开始
var fP=新文件处理器();
foreach(someFiles中的var文件)
{
进度报告(新文件进度(文件,0,“开始”);
//做一些处理
进度报告(新文件进度(文件,100,“完成”);
}
...
});
//我们回到了UI线程中,我们可以修改UI
ReportEnd();
}
async await是一种方法。无论如何,你不应该对代码进行实际操作。它应该通过ViewModel+命令模式来完成。我知道有很多东西需要学习,但如果你要做,最好做对:)@Steve是的,你完全正确,我很欣赏这个手势。我可以问一个适当的提示吗(可能是一个链接或参考书目,一系列视频)?我想很快参与进来,因为在下个月初,我需要将它连接到SQL server,而我的团队合作伙伴中没有一个真正有能力编写代码(如果你知道我的意思的话)。关键词:“MVVM”、“WPF ICommand”、“异步等待”、“c#Task”。用谷歌搜索这些教程,充分了解它们是什么以及如何正确使用它们,然后你就可以开始了。可能需要2周以上的时间才能完成所有工作。掌握Sql需要几个月的时间,所以请记住这一点。我不能说这是否适用于你的特定情况,但请看我在哪里谈论这个特定主题。@scha谢谢你的评论。我很快就会达到顶峰,希望它能给我们带来好处,因为我们真的没时间了(我相信现在是我真正应该说谢谢的时候了。实施这种方法消除了我所有的错误,现在我只有一件事要解决,那就是另一个问题。先生,这个答案非常令人振奋。