ディレクトリ内のすべての画像のリストを取得し、それらすべてに対して MD5 ダイジェストを実行するルーチンがあります。これには時間がかかるため、プログレス バーを含むウィンドウをポップアップ表示します。プログレス バーは、実行時間の長いルーチンに渡すラムダによって更新されます。
最初の問題は、進行状況ウィンドウが更新されないことでした (これは WPF では正常だと思います)。WPF にはRefresh()
コマンドがないため、 への呼び出しでこれを修正しましたDispatcher.Invoke()
。プログレスバーがしばらく更新された後、ウィンドウの更新が停止します。長時間実行されている作業は最終的に終了し、ウィンドウは通常に戻ります。
私はすでに BackgroundWorker を試しましたが、長時間実行されるプロセスによってトリガーされるイベントに関連するスレッドの問題にすぐに不満を感じました。それが本当に最善の解決策であり、パラダイムをよりよく学ぶ必要がある場合は、そう言ってください.
しかし、ここで得たアプローチには本当に満足していますが、少しすると更新が停止します (たとえば、1000 個のファイルを含むフォルダーでは、50 ~ 100 個のファイルが更新されてから「ハング」する可能性があります)。 . 進行状況を報告する場合を除いて、このアクティビティ中に UI が応答する必要はありません。
とにかく、ここにコードがあります。まず進行状況ウィンドウ自体:
public partial class ProgressWindow : Window
{
public ProgressWindow(string title, string supertext, string subtext)
{
InitializeComponent();
this.Title = title;
this.SuperText.Text = supertext;
this.SubText.Text = subtext;
}
internal void UpdateProgress(int count, int total)
{
this.ProgressBar.Maximum = Convert.ToDouble(total);
this.ProgressBar.Value = Convert.ToDouble(count);
this.SubText.Text = String.Format("{0} of {1} finished", count, total);
this.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
}
private static Action EmptyDelegate = delegate() { };
}
<Window x:Class="Pixort.ProgressWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Pixort Progress" Height="128" Width="256" WindowStartupLocation="CenterOwner" WindowStyle="SingleBorderWindow" ResizeMode="NoResize">
<DockPanel>
<TextBlock DockPanel.Dock="Top" x:Name="SuperText" TextAlignment="Left" Padding="6"></TextBlock>
<TextBlock DockPanel.Dock="Bottom" x:Name="SubText" TextAlignment="Right" Padding="6"></TextBlock>
<ProgressBar x:Name="ProgressBar" Height="24" Margin="6"/>
</DockPanel>
</Window>
長時間実行される方法 (Gallery.cs 内):
public void ImportFolder(string folderPath, Action<int, int> progressUpdate)
{
string[] files = this.FileIO.GetFiles(folderPath);
for (int i = 0; i < files.Length; i++)
{
// do stuff with the file
if (null != progressUpdate)
{
progressUpdate.Invoke(i + 1, files.Length);
}
}
}
したがって、これは次のように呼ばれます。
ProgressWindow progress = new ProgressWindow("Import Folder Progress", String.Format("Importing {0}", folder), String.Empty);
progress.Show();
this.Gallery.ImportFolder(folder, ((c, t) => progress.UpdateProgress(c, t)));
progress.Close();