我有一个例程,它抓取目录中所有图像的列表,然后在所有图像上运行MD5摘要。由于这需要一段时间,我弹出一个带有进度条的窗口。进度条由我传入长时间运行的lambda进行更新。首先wpf窗口刷新工作,然后停止
第一个问题是进度窗口从未更新过(这在WPF中是正常的我猜)。由于WPF缺少Refresh()
命令,我通过调用Dispatcher.Invoke()
来解决这个问题。现在进度条会更新一段时间,然后窗口停止更新。长期工作最终会结束,窗户恢复正常。
我已经尝试过一个BackgroundWorker,并且很快就被与长时间运行的进程触发的事件相关的线程问题沮丧。所以如果这真的是最好的解决方案,我只需要更好地学习范例,请说出来。
但是我会非常乐意使用我在这里得到的方法,除了在稍后停止更新(例如,在包含1000个文件的文件夹中,它可能会更新50-100个文件,然后“挂”)。在此活动中,用户界面不需要做出响应,除了报告进度。
无论如何,这是代码。这也是正是如此叫
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);
}
}
}
:一是进度窗口本身:
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)
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();
您知道我在哪里可以找到这个工作示例吗?我尝试了很多不同的东西来让它在没有为代码添加间接层的情况下工作。每次酒吧都没有更新。 – mlibby 2010-03-24 13:03:51
嗨,我发布了代码。核实。 – RockWorld 2010-03-24 14:17:34