Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF-在循环中更新UI时播放声音_C#_Wpf_Multithreading_Audio_Data Binding - Fatal编程技术网

C# WPF-在循环中更新UI时播放声音

C# WPF-在循环中更新UI时播放声音,c#,wpf,multithreading,audio,data-binding,C#,Wpf,Multithreading,Audio,Data Binding,我是WPF的新手,我最终通过更新UI创建了一个for循环。但我搜索了很多网站,没有找到解决问题的方法: 在我的主窗口中,我有一个标签 <Label x:Name="labelName" Content="{Binding LabelNameContent}"/> 标签的文本在循环中得到更新,循环过程中应播放声音 Task.Factory.StartNew(() => { sound.Play(); for(int i=0; i< 150; i++)

我是WPF的新手,我最终通过更新UI创建了一个for循环。但我搜索了很多网站,没有找到解决问题的方法:

在我的主窗口中,我有一个标签

<Label x:Name="labelName" Content="{Binding LabelNameContent}"/>
标签的文本在循环中得到更新,循环过程中应播放声音

Task.Factory.StartNew(() => 
{
    sound.Play();

    for(int i=0; i< 150; i++)
    {
        LabelNameContent = i.ToString();
        Thread.Sleep(500);
    }
});
Task.Factory.StartNew(()=>
{
声音。播放();
对于(int i=0;i<150;i++)
{
LabelNameContent=i.ToString();
睡眠(500);
}
});
我的问题是,声音被打断了,而且一直在结巴


如何更新用户界面并播放声音?

您使用什么课程播放声音?根据类的不同,可能存在一个事件,您可以向其注册处理程序,以便在声音播放结束时收到通知。因此,您可以调用
声音。播放
,等待
自动恢复事件
,然后
在收到声音结束的通知时设置
自动恢复事件。最后,您的循环可以继续。大概是这样的:

在您表格中的班级级别:

AutoResetEvent soundFinishedFlag = new AutoResetEvent(false);
然后,在创建声音播放器的地方,您将执行以下操作:

sound.Finished += SoundFinished;
请注意,上面这一行完全取决于您使用的声音播放器!这只是一个例子

最后,您的匿名函数变成:

Task.Factory.StartNew(() => 
{
    sound.Play();

    // Wait for the sound to finish playing!
    AutoResetEvent.WaitOne();  // Note that this can take an optional time out so you can limit how long your program waits, if you want to.

    for(int i = 0; i < 150; i++)
    {
        LabelNameContent = i.ToString();
        Thread.Sleep(500);
    }
});
Task.Factory.StartNew(()=>
{
声音。播放();
//等待声音结束播放!
AutoResetEvent.WaitOne();//请注意,这可能需要一个可选的超时时间,以便您可以限制程序等待的时间(如果需要)。
对于(int i=0;i<150;i++)
{
LabelNameContent=i.ToString();
睡眠(500);
}
});
当然,如果您使用的声音播放器没有提供“我完成了”的事件通知,这是没有帮助的

编辑

根据您在评论中的回复,您需要让
SoundPlayer
在与UI和更新标签内容的UI分开的线程中播放其声音

我的WPF应用程序使用
SoundPlayer
播放几种不同声音中的一种。每个声音都有自己专用的
SoundPlayer
实例。当我播放声音时,会启动一个新的
线程
&对该
线程
调用
播放
方法。这有以下优点:

  • 播放声音的线程除了播放声音之外没有做任何其他事情
  • 如果您需要在声音播放结束前停止声音,只需停止运行
    SoundPlayer
    的线程即可

  • 嗯,循环的每次迭代都睡半秒钟是没有用的。使用
    Task.Delay
    而不是
    Thread.Sleep
    。使用
    Task.Delay
    用户界面不再更新:/谢谢,但我不想等到声音结束,我希望它在循环运行时播放。另外,我用的是SoundPlayer。谢谢!不知道为什么我没有看到这个简单的解决方案^^Works=)
    Task.Factory.StartNew(() => 
    {
        sound.Play();
    
        // Wait for the sound to finish playing!
        AutoResetEvent.WaitOne();  // Note that this can take an optional time out so you can limit how long your program waits, if you want to.
    
        for(int i = 0; i < 150; i++)
        {
            LabelNameContent = i.ToString();
            Thread.Sleep(500);
        }
    });