读取所有代码后发生的故事板动画.需要它发生之前
本文关键字:动画 的故事 代码 读取 | 更新日期: 2023-09-27 18:31:44
我愿意学习WPF和C#,我决定学习编程语言的最好方法是考虑一个对我有意义的小项目,然后根据需要学习语言功能。
现在,我在"设置"屏幕上有一个按钮,该按钮正在调用执行一些 IO 密集型工作的帮助程序类HarpaEngine
中的一些方法,因此为了给用户一些反馈,我在屏幕上放置了一个 <Path>
对象,当我单击按钮时应该开始旋转,当 IO 工作完成时, 它应该消失。这是我单击按钮时执行的代码:
private void btnSaveSettings_Click(object sender, RoutedEventArgs e)
{
// I created the Storyboard programmatically, don't think that's relevant
// It works though
DoubleAnimation refreshAnimation = new DoubleAnimation();
refreshAnimation.Duration = TimeSpan.FromSeconds(3);
refreshAnimation.From = 0.0;
refreshAnimation.To = 360.0;
refreshAnimation.RepeatBehavior = RepeatBehavior.Forever;
Storyboard storyboard = new Storyboard ();
storyboard.Children.Add(refreshAnimation);
Storyboard.SetTargetName(refreshAnimation, "RefreshAngle");
Storyboard.SetTargetProperty(refreshAnimation, new PropertyPath(RotateTransform.AngleProperty));
//(...) Some work gets done here (...)
RefreshIcon.Visibility = System.Windows.Visibility.Visible;
storyboard.Begin(this);
//HarpaEngine is my helper class
HarpaEngine.MP3Files.Clear();
Task deassign = Task.Run(() => HarpaEngine.DeassignMP3toHymns());
deassign.Wait();
Task populateMP3 = Task.Run(() => HarpaEngine.PopulateMP3Files());
populateMP3.Wait();
Task assign = Task.Run(() => HarpaEngine.AssignMP3toHymns());
assign.Wait();
Task serialize = Task.Run(() => HarpaEngine.SerializeMP3());
serialize.Wait();
storyboard.Stop();
RefreshIcon.Visibility = System.Windows.Visibility.Hidden;
使用此代码,对象永远不会可见。我认为物体变得可见,然后不可见,速度如此之快,以至于肉眼看不到。当我删除最后 2 行以使对象永远不会不可见时,它会在处理完所有行后开始动画。通过使用断点,我发现整个过程大约需要 10 秒才能完成,因此如果对象在处理Task.Run
行之前变得可见,它将完美运行。我尝试使用 async
和 await
而不是 Task.Run
,但要么它不是这里的解决方案,要么我错误地实现了它。我在 MSDN 上阅读了一些关于后台工作者的文章,但他们建议Task.Run
性能更高。
关于我的程序的一些背景上下文:
它有一个嵌入的.txt资源文件,它可以读取我们在教堂里唱的大约640首歌曲的所有歌词,然后在MainWindow
的列表中显示歌曲列表。它还读取一个属性设置,该设置指定存储与这些歌曲相关的所有 MP3 文件的文件夹。"设置"窗口允许用户更改该文件夹的路径,此代码中的按钮调用扫描新文件夹中.mp3文件的方法,然后填充List<MP3file>
,以便在显示歌词列表时,它还为文件夹中有相应.mp3文件的每首歌曲显示一个小的播放按钮。
有人可以指出我正确的方向吗?我想<Path>
只有在完成读取整个代码后才会显示,因为 UIThread 被阻止了。这是一个普通的必需品,但我看到的大多数关于线程和async
的例子都处理更复杂的场景,这些场景对我的问题来说是矫枉过正的,建议的实现涉及我还不知道如何使用的高级 C# 功能。
非常感谢所有的帮助!
PS:请不要以为我知道如何实施您的建议。
它似乎直到工作完成后才开始的原因是因为您正在对任务调用 Wait()。 这会导致线程阻塞,直到它们完成 - 不幸的是,该线程是您的 UI 线程,它也负责旋转轮子。 这意味着您正在启动动画,立即阻止 UI 线程(导致 UI 挂起),然后在完成所有工作后立即释放它。
假设您只有 1 个长时间运行的任务要满足,而不是 3 个。 一种解决方案是将长时间运行的方法转换为返回任务的方法,然后附加 ContinueWith 回调
public Task DoSomethingAsync()
{
return Task.Factory.StartNew(
() => HarpaEngine.DeassignMP3toHymns()
);
}
public void StopAnimation()
{
//stop storyboard
}
然后,在您的按钮中单击
Task doingWork = DoSomethingAsync();
doingWork.ContineWith(OnWorkCompleted);