2014-01-30 2 views
1

Я разрабатываю .NET-библиотеку для удобства использования кода LibTiePie по .NET.Дизайн объекта .NET: аппаратные ручки и сборщик мусора

Соответствующий код библиотеки (C#):

using Handle = UInt32; 

public static class API 
{ 
    [DllImport(@"libtiepie.dll", CallingConvention = CallingConvention.Cdecl)] 
    public static extern void DevClose(Handle device); 
}; 

public class Device 
{ 
    protected Handle _handle; 

    public Device(Handle handle) 
    { 
     _handle = handle; 
    } 

    ~Device() 
    { 
     API.DevClose(_handle); 
    } 
} 

Программный код (C#):

Device dev = new Device(some_valid_open_handle); 

// Do something useful with dev 

dev = null; // How can I make sure that the handle is closed now, as the GC may not cleanup it directly? 

Я могу добавить Close СПОСОБА Device класса, который можно назвать, прежде чем отпустить ссылку. Но удивительно, что есть лучший способ реализации этого метода .NET?

+3

Внедрите шаблон IDisposable. Затем потребители могут: «использовать (устройство d = новое устройство (дескриптор)) {...}' и получить детерминированное закрытие основного дескриптора – jglouie

+0

@jglouie: сделать этот ответ до того, как кто-то еще сделает –

+0

Возможно, я ошибаюсь, но я подумайте, что вы хотите использовать 'IntPtr', а не' UInt32' для типа 'Handle'. – Lukazoid

ответ

2

Внедрение интерфейса IDisposable.

Потребители могут затем сделать:

using (Device d = new Device(handle)) 
{ 
    ... 
} 

Это даст детерминированный закрытие основной рукоятки. Также см. Документацию по ключевому слову using.

Вместо того, чтобы звонить API.DevClose(_handle) в финализаторе, вы должны сделать это в Dispose(). Ссылка MSDN имеет хороший пример того, как этот шаблон можно использовать для закрытия собственных дескрипторов.

+0

Если сборка и очистка не входят в ту же область действия, я должен выполнить очистку, используя: 'dev.Dispose(); dev = null; '? – Reinder

+0

точно - 'использование' не всегда подходит. В этом случае вызовите 'Dispose', если это безопасно. Часто это находится в обработке родительского контейнера 'Dispose' – jglouie

Смежные вопросы