Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.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_User Interface_Async Await - Fatal编程技术网

C# WPF应用程序不确定进度条不';不显示,但进程正在后台运行

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以向用户提供进程没有崩溃的线索时,可能遇到了线程问题。既然这已经足够了,一个无限的进度条对我来说很好

 <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谢谢你的评论。我很快就会达到顶峰,希望它能给我们带来好处,因为我们真的没时间了(我相信现在是我真正应该说谢谢的时候了。实施这种方法消除了我所有的错误,现在我只有一件事要解决,那就是另一个问题。先生,这个答案非常令人振奋。