プロセスを機能させると、ProgressBarを追加してプロセスがクラッシュしていないことをユーザーに知らせるために、スレッドの問題が発生した可能性があります。これで十分なので、IndefiniteProgressBarは私にとっては問題ありません。
<ProgressBar x:Name="ProcessProgress" Minimum="0" Maximum="100" Visibility="Hidden" IsIndeterminate="False" Width="305" Height="20" Margin="240,214,248,10"></ProgressBar>
スタートボタンがクリックされる前に表示されない長さの決定的なプログレスバーを開始しようとしました:
private void Start_Click(object sender, RoutedEventArgs e)
{
...
//process starts here
var fP = new FileProcessor();
ProcessProgress.IsIndeterminate = true;
ProcessProgress.Visibility = Visibility.Visible;
...
//finally show the progressbar as full when done
ProcessProgress.IsIndeterminate = false;
ProcessProgress.Value = ProcessProgress.Maximum;
}
プロセス全体を実行するだけで、バーが表示されません。
プロセス中にプログレスバーを生成するにはどうすればよいですか?
問題は、すべてのコードが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スレッドに戻るために使用する必要はありませんawait
。それ自体が仕事です。
についてのメモasync void
。これは、イベントハンドラーまたは同様のメソッドのみを対象としています。メソッドを待つことはできませんasync void
。つまり、何か問題が発生した場合でも例外を取得することはできません。何も返さない非同期メソッドには、async Task
署名が必要です。
進行状況を報告する場合は、ここで説明するように、IProgressインターフェイスとProgressクラスを使用できます。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();
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加