2014-01-16 118 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