调用FinishedPlaying事件时,如何处置AVAudioPlayer?

Dav*_*lfe 4 c# xamarin.ios ios

当用户在UITableView中点击一行时,我正在使用AVAudioPlayer播放声音。如果他们再次轻按该行,则播放器停止并被处置,如果他们听完这首歌直到完成,则FinshedPlaying处理程序将处置该播放器。

我遇到的问题是,当我尝试在FinishedPlaying处理程序中处置播放器时,出现错误消息:

System.ObjectDisposedException:播放器对象在回调过程中被Dispose()d破坏了程序的状态

这是代码,知道我在做什么错吗?

void HandleOnRequestPlayMusic (object sender, UrlEventArgs e)
{
    var url = Utils.UrlFromString(e.Url);
    string oldUrl = "";
    if (musicPlayer != null)
    {
        oldUrl = musicPlayer.Url.AbsoluteString;
        KillAudioPlayer(); // no problems killing the audio player from here
    }
    if (oldUrl != url.AbsoluteString)
    {
        musicPlayer = AVAudioPlayer.FromUrl(url);
        musicPlayer.FinishedPlaying += HandleAudioFinished;
        musicPlayer.Play();
    }
}

void HandleAudioFinished (object sender, AVStatusEventArgs e) 
{
    KillAudioPlayer(); // killing audio player from here causes app to crash
}

void KillAudioPlayer ()
{
    if (musicPlayer != null)
    {
        InvokeOnMainThread(() => {
            musicPlayer.Stop();
            musicPlayer.FinishedPlaying -= HandleAudioFinished;
            musicPlayer.Dispose();
            musicPlayer = null;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

Aar*_*den 5

不要在那里使用InvokeOnMainThread,因为InvokeOnMainThread等待输入操作完成后再返回其调用方。这就是为什么你还在电话里给你的Dispose来电时KillAudioPlayer,里面的HandleAudioFinished回调。

而是使用BeginInvokeOnMainThread,它将安排您的清理操作在主线程上进行,但会立即返回到KillAudioPlayer函数,使其完成。