WinUI3媒体播放器按钮失效及ArgumentException异常修复求助
WinUI3 媒体播放器命令按钮异常问题
问题现象
- 仅快进按钮功能正常
- 后退按钮点击一次后失效
- 上一曲、下一曲按钮无任何响应
- 断点调试显示仅
CommandManager_FastForwardReceived函数被触发,其余处理函数均未执行 - 尝试修复过程中抛出异常:
Exception thrown: 'System.ArgumentException' in WinRT.Runtime.dll
相关代码
事件注册代码
mp.MediaPlayer.CommandManager.PreviousReceived += CommandManager_PreviousReceived; mp.MediaPlayer.CommandManager.FastForwardReceived += CommandManager_FastForwardReceived; mp.MediaPlayer.CommandManager.RewindReceived += CommandManager_RewindReceived;
事件处理函数
private void CommandManager_NextReceived(MediaPlaybackCommandManager sender , MediaPlaybackCommandManagerNextReceivedEventArgs args) { DispatcherQueue.TryEnqueue(() => { args.Handled = true; PlayNextInQueue(); }); } private void CommandManager_PreviousReceived(MediaPlaybackCommandManager sender , MediaPlaybackCommandManagerPreviousReceivedEventArgs args) { DispatcherQueue.TryEnqueue(() => { args.Handled = true; PlayPreviousInQueue(); }); } private void CommandManager_FastForwardReceived(MediaPlaybackCommandManager sender , MediaPlaybackCommandManagerFastForwardReceivedEventArgs args) { args.Handled = true; if ((mp.MediaPlayer.PlaybackSession.NaturalDuration.TotalSeconds - mp.MediaPlayer.Position.TotalSeconds) <= 5) { PlayNextInQueue(); } else { mp.MediaPlayer.Position += TimeSpan.FromSeconds(5); } } private void CommandManager_RewindReceived(MediaPlaybackCommandManager sender , MediaPlaybackCommandManagerRewindReceivedEventArgs args) { DispatcherQueue.TryEnqueue(() => { args.Handled = true; if (mp.MediaPlayer.Position.TotalSeconds > 5) { mp.MediaPlayer.Position -= TimeSpan.FromSeconds(5); } else { mp.MediaPlayer.Position = TimeSpan.Zero; } }); }
修复方案
补全事件注册
下一曲按钮无响应是因为未注册NextReceived事件,添加以下代码:mp.MediaPlayer.CommandManager.NextReceived += CommandManager_NextReceived;修正DispatcherQueue使用逻辑
后退、上一曲等按钮失效的核心原因是:在异步队列中设置args.Handled = true,导致系统无法及时识别事件已处理,进而出现重复触发或失效。需先同步标记事件已处理,再将UI相关操作放入DispatcherQueue:- 修改
CommandManager_PreviousReceived:private void CommandManager_PreviousReceived(MediaPlaybackCommandManager sender , MediaPlaybackCommandManagerPreviousReceivedEventArgs args) { args.Handled = true; DispatcherQueue.TryEnqueue(() => { PlayPreviousInQueue(); }); } - 修改
CommandManager_RewindReceived:private void CommandManager_RewindReceived(MediaPlaybackCommandManager sender , MediaPlaybackCommandManagerRewindReceivedEventArgs args) { args.Handled = true; DispatcherQueue.TryEnqueue(() => { if (mp.MediaPlayer.Position.TotalSeconds > 5) { mp.MediaPlayer.Position -= TimeSpan.FromSeconds(5); } else { mp.MediaPlayer.Position = TimeSpan.Zero; } }); } - 修改
CommandManager_NextReceived:private void CommandManager_NextReceived(MediaPlaybackCommandManager sender , MediaPlaybackCommandManagerNextReceivedEventArgs args) { args.Handled = true; DispatcherQueue.TryEnqueue(() => { PlayNextInQueue(); }); }
- 修改
排查ArgumentException异常
该异常通常由线程不安全访问或操作已释放对象导致:- 确保
mp.MediaPlayer在事件触发时未被销毁或释放 - 所有对MediaPlayer及其属性的访问都通过
DispatcherQueue.TryEnqueue切换到UI线程执行 - 检查
PlayNextInQueue和PlayPreviousInQueue方法,确认是否存在传递无效参数(如空媒体源)的情况
- 确保
内容的提问来源于stack exchange,提问作者tribeti
相关产品推荐
相关产品推荐

