You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用NAudio的WaveOutEvent播放WAV文件触发NullReferenceException问题排查

NAudio播放WAV文件时出现NullReferenceException异常问题

问题场景

在WPF应用中使用NAudio的WaveOutEvent播放MP3和WAV文件,MP3播放正常,但播放WAV文件时,调用player.Play()后,NAudio.Core抛出NullReferenceException,提示“未将对象引用设置到对象的实例”。

代码示例

using (AudioFileReader afr = new AudioFileReader(_filename))
{
  OffsetSampleProvider osp = new OffsetSampleProvider(afr);
  osp.SkipOver = currentCursorPosition;
  osp.Take = PlaybackDuration;

  WaveOutEvent player = new WaveOutEvent();
  player.Init(osp);
  player.Play();
}

异常信息

  • Exception.Source: NAudio.Core
  • Exception.StackTrace: 在**NAudio.Wave.WaveFileReader.get_Position()**处
  • 模块版本: NAudio.Core.dll 2.01.0.0

问题原因

核心原因是AudioFileReader被using语句提前释放。WaveOutEvent是异步播放,using块会在player.Play()调用后立即执行Dispose,此时后台播放线程仍在运行。处理WAV文件时,AudioFileReader内部的WaveFileReader实例被释放后变为null,线程读取数据调用其Position属性时触发空引用异常。

MP3播放正常是因为AudioFileReader处理MP3时使用的Mp3FileReader内部实现不会在Dispose后立即导致核心读取对象失效,和WAV的WaveFileReader资源释放逻辑不同。

解决方法

方法1:移除using语句,通过播放结束事件手动释放资源

确保AudioFileReader在播放全程保持有效,监听PlaybackStopped事件,在播放结束后再释放相关资源:

var afr = new AudioFileReader(_filename);
var osp = new OffsetSampleProvider(afr);
osp.SkipOver = currentCursorPosition;
osp.Take = PlaybackDuration;

var player = new WaveOutEvent();
player.PlaybackStopped += (s, e) =>
{
    player.Dispose();
    afr.Dispose();
};
player.Init(osp);
player.Play();

方法2:避免提前释放音频读取器

绝对不要将AudioFileReader放在using块中,因为异步播放时,using块的生命周期远短于播放线程的运行周期,会导致资源提前释放引发异常。

内容的提问来源于stack exchange,提问作者Aaginor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:42:28