首页 > 解决方案 > 从单个函数“使用”多个 IDisposable

问题描述

我有一个返回NativeList<>结构的方法AStruct,其中NativeList<>是实现的非托管内存的包装器IDisposable。AStruct 包含另一个由 a 支持的指针,该指针NativeList<float>也是在同一方法中创建的,因此:

private unsafe NativeList<AStruct> GetAStructs()
{
    var floatList = new NativeList<float>();
    floatList.Add(0.0f);

    var list = new NativeList<AStruct>();

    AStruct a1 = new AStruct();
    a1.floats = (float*)floatList.Data;
    list.Add(a1);

    // ...

    return list;
}

这是一个问题,因为 nowfloatList在调用GetAStructs(). 所以我更改了方法签名以包含一个 out 参数。

private unsafe NativeList<AStruct> GetAStructs(out IDisposable toDispose)
{
    // ...

    toDispose = floatList;
    return list;
}

我这样称呼它

using (NativeList<AStruct> disposableList = GetAStructs(out IDisposable toDispose))
using (toDispose)
{
    callNativeFunction((AStruct*)disposableList.Data);
}

这会按预期工作吗?有没有办法在不向调用方法公开实现细节的情况下做到这一点?

标签: c#pointers

解决方案


我承认我对 NativeArray 了解不多,但在这种情况下,您通常可以通过创建正在使用的类的子类来获得所需的功能。

在这种情况下,我建议您创建一个NativeList包含处理回调的子类。向它传递一个函数,该函数将完成您之前要求调用者完成的工作。

示例子类:

class MyNativeList<T> : NativeList<T>
{
    protected readonly Action _callAfterDisposal;

    public MyNativeList(Action callAfterDisposal) : base()
    {
        _callAfterDisposal= callAfterDisposal;
    }

    public override Dispose()
    {
        base.Dispose();
        _callAfterDisposal();
    }
}

设置回调:

private unsafe NativeList<AStruct> GetAStructs()
{
    var floatList = new NativeList<float>();
    floatList.Add(0.0f);

    //here we construct the MyNativeList and pass it an action to execute when it is disposed
    var list = new MyNativeList<AStruct>( () => {
        callNativeFunction((AStruct*)floatList.Data);
        floatList.Dispose();
    });

    AStruct a1 = new AStruct();
    a1.floats = (float*)floatList.Data;
    list.Add(a1);

    // ...

    return list;
}

当您这样做时,浮点数的本机列表被捕获在一个封闭变量中。您的调用者只需要按正常方式处理列表,并且在进行回调时,也会处理本机浮动列表。

using ( var disposableList = GetAStructs() ) 
{
    //Do stuff
}

请注意,它GetAStructs()仍然返回对 a NativeList<T>(不是 a MyNativeList<>)的引用,因此实现细节不会泄漏给调用者,除非他们竭尽全力转换结果。


推荐阅读