c# - 调用 FinishedPlaying 事件时如何处理 AVAudioPlayer?

标签 c# ios xamarin.ios

我正在使用 AVAudioPlayer 在用户点击 UITableView 中的一行时播放声音。如果他们再次点击该行,则播放器会停止并被处理掉,如果他们一直听这首歌直到它结束,则 FinshedPlaying 处理程序会处理掉播放器。

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

System.ObjectDisposedException: the player object was Dispose()d during the callback, this has corrupted the state of the program

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

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;
        });
    }
}

最佳答案

不要使用 InvokeOnMainThread在那里,因为 InvokeOnMainThread 在返回其调用者之前等待输入操作完成。这就是为什么您仍在 HandleAudioFinished 回调内调用 KillAudioPlayer 时发生 Dispose 调用的原因。

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

关于c# - 调用 FinishedPlaying 事件时如何处理 AVAudioPlayer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16742785/

相关文章:

ios - 在运行时枚举UISupportedExternalAccessoryProtocols

iphone - 在 monotuch 中通过 CGBitmapContext 组合两个图像时如何避免质量损失

c# - Index-1 没有值

c# - 我应该使用数据库模拟进行单元测试吗

ios - PresentModalViewController 一旦应用程序从 Framework 启动

ios - 从使用 MessageKit 创建的 ChatViewController 推送其他 ViewController

c# - JSON 序列化程序写入过多 ']'

c# - 如何从数据集中获取数据到 gridview?

iphone - 重新创建 NSMutableArray 重新初始化后的内存

ios - 单点触控 : How to dismiss any open UIAlertViews