2014-01-16 201 views
0

我一直在这个论坛以及MSDN环顾四周,但我无法真正找到适合我的问题的解决方案。可能我的做法不好。 我有以下简单的类,它有一个简单的方法(“PlayAudioFile”)。我想要做的就是等待播放完成,然后让方法结束并继续。由于.Play()是异步的,所以方法在播放完成之前完成,这对我并不好,因为我想同步播放几个文件(一个接一个播放)。我试图使用AutoResetEvent w/o运气,因为当播放结束时,我不进入“MediaEnded”回调.... 1解决方案我不想使用是有一个while()循环忙等待一个标志提出在MediaEnded的信号中表示播放已完成。它看起来不对。如何同步异步操作?

任何想法?

public class Audio 
{ 
    AutoResetEvent are = new AutoResetEvent(false); 
    public void PlayAudioFile(string file) 
    { 
     MediaPlayer mediaPlayer = new MediaPlayer(); 
     mediaPlayer.MediaEnded += m_MediaEnded; 
     mediaPlayer.Open(new Uri(file)); 
     mediaPlayer.Play(); 
     are.WaitOne(); 

    } 

    private void m_MediaEnded(object sender, EventArgs e) 
    { 
     MediaPlayer mediaPlayer = (MediaPlayer)sender; 
     mediaPlayer.Close(); 
     mediaPlayer = null; 
     are.Set(); 
    } 

} 
+0

什么样的应用呢?在大多数类型的应用程序中,您不能“等待”I/O操作。 –

+0

嗨Henk,这是一个WinForm应用程序,它使用这个上面的类。 WinForm应用程序需要同步播放音频文件,因此它基本上需要等待... – LorenB

+0

您还可以处理'MediaFailed'事件,并在播放结束之前查看是否发生错误。它似乎可以优雅地结束,但不是。 – Abhinav

回答

2

如果正在使用.NET Framework> = 4.5,则可以利用异步/ AWAIT。您的代码可以是这样的(对不起,我盲目地编写它)

await PlayAudioFile(somefile); 

public Task PlayAudioFile(string file) 
{ 
    var tcs = new TaskCompletionSource<bool>(); 
    MediaPlayer mediaPlayer = new MediaPlayer(); 
    mediaPlayer.MediaEnded += (sender, e) => 
     { 
      mediaPlayer.Close(); 
      tcs.TrySetResult(true); 
     }; 
    mediaPlayer.Open(new Uri(file)); 
    mediaPlayer.Play(); 
    return tcs.Task; 
} 
+0

谢谢,这工作很好,虽然在我的其他情况下,它没有。我会发布一个单独的线程,作为requried。 – LorenB

+1

也把mediaPlayer作为一个字段。在我的情况下,音频文件只播放了一小部分,原来它是垃圾收集。 – RvdK