Dear.Va 2020-08-02 10:37 采纳率: 0%
浏览 215

SharpDX中怎样释放Bitmap资源?

我使用了SharpD2D1来在屏幕上显示图像。

我使用了SharpDX的示例创建SwapChain用于在屏幕上显示。

public static D2D.RenderTarget Target { get; private set; }
public readonly Device device;
public bool isFormClosed = false;
private readonly DXGI.Factory factory;
private readonly Texture2D backBuffer;
private readonly D2D.Factory factory2D;
private readonly DXGI.SwapChain swapChain;
private readonly RenderTargetView backBufferView;

public DXMagager() {
    Width = Screen.PrimaryScreen.Bounds.Width;
    Height = Screen.PrimaryScreen.Bounds.Height;
    Left = Top = 0;

    var desc = new DXGI.SwapChainDescription() {
        BufferCount = 1,
        ModeDescription = new DXGI.ModeDescription(Width, Height, new DXGI.Rational(300, 1), DXGI.Format.R8G8B8A8_UNorm),
        IsWindowed = true,
        OutputHandle = Handle,
        SampleDescription = new DXGI.SampleDescription(1, 0),
        SwapEffect = DXGI.SwapEffect.Discard,
        Usage = DXGI.Usage.RenderTargetOutput
    };

    Device.CreateWithSwapChain(D3D.DriverType.Hardware, DeviceCreationFlags.BgraSupport, new[] { D3D.FeatureLevel.Level_10_0 }, desc, out device, out swapChain);
    factory = swapChain.GetParent<DXGI.Factory>();
    factory.MakeWindowAssociation(Handle, DXGI.WindowAssociationFlags.IgnoreAll);
    backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0);
    backBufferView = new RenderTargetView(device, backBuffer);
    factory2D = new D2D.Factory();
    using (var surface = backBuffer.QueryInterface<DXGI.Surface>()) {
        Target = new D2D.RenderTarget(factory2D, surface, new D2D.RenderTargetProperties(new D2D.PixelFormat(DXGI.Format.Unknown, D2D.AlphaMode.Premultiplied)));
    }
    Target.AntialiasMode = D2D.AntialiasMode.PerPrimitive;
}

public void Run() {
    device.ImmediateContext.Rasterizer.SetViewport(0, 0, Width, Height);
    device.ImmediateContext.OutputMerger.SetTargets(backBufferView);
    using (var loop = new RenderLoop(this)) {
        while (loop.NextFrame()) {
            BeginDraw();
            if (!isFormClosed) {
                Draw();
            }
            EndDraw();
        }
    }
    backBufferView.Dispose();
    backBuffer.Dispose();
    device.Dispose();
    Target.Dispose();
    swapChain.Dispose();
    factory.Dispose();
}

之后我用这样的方式加载了100张Bitmap来绘制:

MemUsed = width * height * 4;
IntPtr intPtr = Marshal.AllocHGlobal(MemUsed);
unsafe {
  slide.ReadRegion(level, x, y, width, height, (void*)intPtr);  // 这句是加载一种格式的图片到intPtr,可以理解为Stream
}
BitmapProperties props = new BitmapProperties(new PixelFormat(Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Ignore));
DataPointer pointer = new DataPointer(intPtr, MemUsed);
Bitmap = new Bitmap(DXMagager.Target, new Size2(width, height), pointer, width * 4, props);
Marshal.FreeHGlobal(intPtr);  // 释放预分配的内存

但是我发现,如果把这100张Bitmap全部Dispose之后直接关闭DX窗口,那么其内存不会被释放。但如果不直接关闭DX窗口,那么过一段时间内存会被自动释放掉。请问这里到底发生了什么呢?

附SharpDX中对Dispose的解释:http://sharpdx.org/wiki/usage/

  • 写回答

2条回答 默认 最新

  • jingluan666 2020-08-02 11:31
    关注

    把需要释放资源的代码尽量放在using内

    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?