«использование» нескольких IDisposables из одной функции - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть метод, который возвращает 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 голосов
/ 21 сентября 2018

Признаюсь, я не знаю много о 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() по-прежнему возвращает ссылку на NativeList<T> (не * MyNativeList<>), поэтому детали реализации не будут передаваться вызывающей стороне, если они не сделают все возможное, чтобы привести результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...