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
相关产品推荐
相关产品推荐

