通过单个功能“使用”多个IDisposable

时间:2018-09-21 19:09:15

标签: c# pointers

我有一个返回NativeList<>结构AStruct的方法,其中NativeList<>是实现IDisposable的非托管内存的包装。 AStruct包含由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;
}

这是一个问题,因为现在在调用floatList之后不再引用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);
}

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

1 个答案:

答案 0 :(得分:1)

我承认我对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;
}

执行此操作时,浮点数的本机列表将捕获在一个封闭变量中。您的呼叫者只需要按常规处理该列表,并且在进行回调时,也会处理本机的float列表。

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

请注意,GetAStructs()仍返回对NativeList<T>的引用(不是MyNativeList<>),因此实现细节不会泄漏给调用者,除非它们竭尽所能地投射结果。