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

WinUI3中CoreDispatcher转DispatcherQueue适配AudioGraph事件处理

WinUI3中用DispatcherQueue替代CoreDispatcher处理AudioGraph事件的正确方式

问题根源

你遇到的Object reference not set to an instance of an object错误,是因为WinUI3的Window类不再提供Dispatcher属性(这是UWP时期的API),直接调用Dispatcher.RunAsync会导致空引用。WinUI3中统一使用DispatcherQueue来实现UI线程调度。

代码转换步骤

1. 替换CoreDispatcher为DispatcherQueue

将原来的事件处理方法,从依赖CoreDispatcher改为使用DispatcherQueue:

原来的错误代码:

private async void FileInputNodeOnFileCompleted(AudioFileInputNode sender, object args) {
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        sender.Stop();               
        sender.Reset();        
    }); 
}

修改后的正确代码:

private void FileInputNodeOnFileCompleted(AudioFileInputNode sender, object args)
{
    // 使用Window的DispatcherQueue将操作调度到UI线程
    _ = DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        sender.Stop();               
        sender.Reset();
        // 同步更新UI状态,修复播放结束后按钮状态未重置的问题
        playButton.Content = "Play Recorded File";
        graph2.Stop();
    });
}

关键差异说明

  • WinUI3的Window内置DispatcherQueue属性,直接通过this.DispatcherQueue即可获取,无需额外初始化
  • DispatcherQueue.TryEnqueue是同步方法,返回布尔值表示是否成功将任务加入队列,不需要用await
  • 新增了UI状态更新逻辑,原代码播放结束后按钮仍显示停止状态,这里一起修复

额外代码优化建议

你的测试代码中还有一处逻辑问题:在TogglePlay方法里,刚创建fileInputNode后就判断Position == TimeSpan.FromSeconds(0)并立即停止播放,这会导致刚点击播放就自动停止。建议删除这段逻辑:

// 删除以下代码块
if (fileInputNode.Position == TimeSpan.FromSeconds(0))
{
    graph2.Stop();
    playButton.Content = "Play Recorded File";
}

完整修改后的核心代码片段

结合所有调整,最终的事件处理方法和播放逻辑如下:

private void FileInputNodeOnFileCompleted(AudioFileInputNode sender, object args)
{
    _ = DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        sender.Stop();               
        sender.Reset();
        playButton.Content = "Play Recorded File";
        graph2.Stop();
    });
}

private async void TogglePlay()
{
    //Toggle playback
    if (playButton.Content.Equals("Play Recorded File"))
    {
        if (fileInputNode != null) {
            fileInputNode.Dispose();
        }
        CreateAudioFileInputNodeResult fileInputResult = await graph2.CreateFileInputNodeAsync(file);
        if (AudioFileNodeCreationStatus.Success != fileInputResult.Status)
        {
            // Cannot read input file
            return;
        }

        fileInputNode = fileInputResult.FileInputNode;
        fileInputNode.AddOutgoingConnection(deviceOutputNode2);
        fileInputNode.StartTime = TimeSpan.FromSeconds(0);

        graph2.Start();
        playButton.Content = "Stop Playing Recorded File";
        fileInputNode.FileCompleted += FileInputNodeOnFileCompleted;
    }
    else
    {
        graph2.Stop();
        playButton.Content = "Play Recorded File";
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 12:54:53