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

SharpDX UWP SwapChain调用Present时触发空引用异常求助

问题分析与修复方案

核心问题:SwapChain 被提前释放

你的空引用异常直接原因是**swapChain 成员变量在初始化完成后被自动释放**。在 InitializeSwapChain 方法中,你用 using 语句包裹了 swapChain 的创建:

using (swapChain = new SwapChain1(factory, dxgiDevice, ref swapChainDesc))

using 块结束时会自动调用 swapChain.Dispose(),同时将成员变量置为 null,后续调用 RenderFrame 里的 swapChain.Present() 自然触发空引用异常。

具体修复步骤

1. 移除 swapChain 的 using 包裹,手动管理资源

将 swapChain 的创建从 using 块中移出,改为在类的 Dispose 方法中统一释放资源(需要让类实现 IDisposable):

// 修改 InitializeSwapChain 中的 swapChain 创建部分
using (var dxgiDevice = device.QueryInterface<SharpDX.DXGI.Device>())
{
    using (var adapter = dxgiDevice.Adapter)
    {
        using (var factory = adapter.GetParent<Factory2>())
        {
            // 移除外层 using,直接创建 swapChain
            swapChain = new SwapChain1(factory, dxgiDevice, ref swapChainDesc);
            
            var swapChainPanel = this._swapChainPanel;
            var swapChainPanelNative = ComObject.As<SharpDX.DXGI.ISwapChainPanelNative>(swapChainPanel);
            swapChainPanelNative.SwapChain = swapChain;

            // Set render view
            backBuffer = swapChain.GetBackBuffer<Texture2D>(0);
            renderTargetView = new RenderTargetView(device, backBuffer);
            device.ImmediateContext.OutputMerger.SetRenderTargets(renderTargetView);

            // Set render target texture
            renderTargetTexture = new Texture2D(device, textureDesc);
            direct3DSurface = Direct3D11Helper.CreateDirect3DSurfaceFromSharpDXTexture(renderTargetTexture);

            // 不要在这里 Dispose backBuffer,留到类销毁时处理
        }
    }
}

2. 修复 textureDesc 未定义的宽高

textureDesc 中的 Width 和 Height 使用了未定义的变量 width 和 height,需要替换为实际值:

var panelWidth = (int)_swapChainPanel.ActualWidth;
var panelHeight = (int)_swapChainPanel.ActualHeight;

// SwapChain 描述
SwapChainDescription1 swapChainDesc = new SwapChainDescription1()
{
    Width = panelWidth,
    Height = panelHeight,
    // 其他属性保持不变
};

// Texture2D 描述
var textureDesc = new Texture2DDescription
{
    Width = panelWidth,
    Height = panelHeight,
    // 其他属性保持不变
};

3. 初始化 deviceContext 成员变量

在创建 device 后,将 deviceContext 赋值为设备的即时上下文:

// Create Direct3D device and context
var creationFlags = DeviceCreationFlags.BgraSupport;
creationFlags |= DeviceCreationFlags.Debug;
device = new Device(SharpDX.Direct3D.DriverType.Hardware, creationFlags);
deviceContext = device.ImmediateContext; // 新增这行

4. 添加资源释放逻辑

让类实现 IDisposable,在 Dispose 方法中释放所有 DirectX 资源:

public void Dispose()
{
    renderTargetView?.Dispose();
    backBuffer?.Dispose();
    renderTargetTexture?.Dispose();
    swapChain?.Dispose();
    deviceContext?.Dispose();
    device?.Dispose();
}

额外注意事项

  • 确保 SwapChainPanel 的 Loaded 事件确实触发(比如面板已正确添加到可视化树中),否则 InitializeSwapChain 不会执行,swapChain 仍为 null。
  • 若后续仍有异常,可开启 Direct3D 调试模式(你已设置 DeviceCreationFlags.Debug),查看输出窗口中的调试信息,定位更底层的资源问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:30:53