读取所有代码后发生的故事板动画。需要它发生在之前

时间:2014-11-22 19:02:39

标签: c# wpf task

我愿意学习WPF和C#,我决定学习编程语言的最好方法是想出一个对我有意义的小项目,然后在我需要的时候学习语言功能。

现在,我在一个设置屏幕上有一个按钮,它调用辅助类HarpaEngine中的某些方法来执行一些IO密集型工作,所以为了给用户一些反馈,我放了一个{{当我点击按钮时,屏幕上的对象应该开始旋转,当IO工作完成时,它应该消失。这是我单击按钮时执行的代码:

<Path>

使用此代码,对象永远不可见。我认为物体变得可见,然后看得那么快,以至肉眼看不见。当我删除最后2行以使对象永远不会被隐藏时,它会开始动画 AFTER 处理所有行。通过使用断点,我发现整个过程大约需要10秒才能完成,因此如果对象变得可见 BEFORE 处理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; 行,它将完美地工作。我尝试使用Task.Runasync代替await,但要么它不是解决方案,要么我错误地实现了它。我在MSDN上阅读了一些关于后台工作者的文章,但是他们认为Task.Run性能更高。

关于我的计划的一些背景情况:

它有一个嵌入的.txt资源文件,它可以读取我们在教堂里唱的大约640首歌曲的所有歌词,然后在Task.Run的列表中显示歌曲列表。它还读取属性设置,该属性设置指定存储与这些歌曲相关的所有MP3文件的文件夹。 “设置”窗口允许用户更改该文件夹的路径,此代码中的按钮调用扫描新文件夹中.mp3文件的方法,然后填充MainWindow,这样,当列表歌词显示,它还为每首歌曲显示一个小的“播放”按钮,文件夹中有相应的.mp3文件。

有人能指出我正确的方向吗?我想List<MP3file>仅在完成读取整个代码之后显示,因为UIThread被阻止。这是一个普通的必需品,但我看到的大多数关于Threads和<Path>的例子都涉及更复杂的场景,这对我的问题来说太过分了,建议的实现涉及我不知道的高级C#功能。如何使用。

非常感谢所有的帮助!

PS:请不要假设我知道如何实施您的建议。

1 个答案:

答案 0 :(得分:0)

在工作完成之后似乎没有开始的原因是因为你在任务上调用Wait()。这导致线程阻塞直到它们完成 - 不幸的是,该线程是你的UI线程,它也负责旋转轮子。这意味着您正在启动动画,立即阻止UI线程(导致UI挂起),然后在完成所有工作后立即释放它。

假设您只有1个长期运行的任务而不是3个内容。一种解决方案是将长时间运行的方法转换为返回Tasks的方法,然后附加一个ContinueWith回调

public Task DoSomethingAsync()
{
    return Task.Factory.StartNew(
        () => HarpaEngine.DeassignMP3toHymns()
    );
}

public void StopAnimation()
{
    //stop storyboard
}

然后,在按钮中单击

Task doingWork = DoSomethingAsync();
doingWork.ContineWith(OnWorkCompleted);