locked
Types that own native resources should be disposable error - how to clear RRS feed

  • Question

  • I have a project with this class, which stores information about a WinUsb device:
    internal class DeviceInfo {  internal SafeFileHandle deviceHandle;
            internal IntPtr winUsbHandle;
            internal Byte bulkInPipe;
            internal Byte bulkOutPipe;
            internal Byte interruptInPipe;
            internal Byte interruptOutPipe;
            internal UInt32 deviceSpeed;}        
    Doing Build > Run code analysis results in this message:

    CA1049 Types that own native resources should be disposable
    Implement IDisposable on 'WinUsbDevice.DeviceInfo'.
    WinUsb_cs - WinUsbDevice.cs (Line 30)

    Following the example here:

    http://msdn.microsoft.com/en-us/library/ms182173.aspx

    I replaced the DeviceInfo class above with:

    public class UnmanagedResources : IDisposable
    {
        public class DeviceInfo
        {
            internal SafeFileHandle DeviceHandle;
            internal IntPtr WinUsbHandle;
            internal Byte BulkInPipe;
            internal Byte BulkOutPipe;
            internal Byte InterruptInPipe;
            internal Byte InterruptOutPipe;
            internal UInt32 DeviceSpeed;
        }
        bool disposed = false;
     
        public UnmanagedResources()
        {
            // Allocate the unmanaged resource ...                        
        }
     
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
     
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    // Release managed resources.
                }
     
                // Free the unmanaged resource ...                    
     
                disposed = true;
            }
        }
     
        ~UnmanagedResources()
        {
            Dispose(false);
        }
    }
    Am I on the right track, and if so, how do I:

    Allocate the unmanaged resource

    and

    Free the unmanaged resource

    to clear the error message?

    Additional information:

    The code above is in my solution's WinUsbCommunications class.

    In my FrmMain class, I create a DeviceInfo object:

    private WinUsbCommunications.UnmanagedResources.DeviceInfo _myDeviceInfo
    
     = new WinUsbCommunications.UnmanagedResources.DeviceInfo();
    Other code in FrmMain passes _myDeviceInfo in calls to WinUsbCommunications functions that access the WinUsb device.

    Sunday, April 21, 2013 6:32 PM

Answers

  • Viorel,

    It's only deviceHandle that causes the error, not WinUsbHandle.

    The DeviceInfo class is defined in the WinUsbCommunications class. The _myDeviceInfo object is defined in the frmMain class. Thus I'm not clear on how to use Dispose in the DeviceInfo class to dispose of the _myDeviceInfo object.

    This is the definition of _myDeviceInfo:

    private WinUsbCommunications.UnmanagedResources.DeviceInfo _myDeviceInfo = 
    new WinUsbCommunications.UnmanagedResources.DeviceInfo();
    If I remove WinUsbHandle from the DeviceInfo class, I get no errors. This means that routines in frmMain must pass two parameters (WinUsbHandle and myDeviceInfo) instead of one (myDeviceInfo) to many functions in WinUsbCommunications. But maybe that's the easiest way to handle this.
    • Marked as answer by Jan Axelson Monday, April 29, 2013 3:07 PM
    Tuesday, April 23, 2013 5:33 PM

All replies

  • Hi Jan,

    >>Allocate the unmanaged resource  

    You need the Marshal Class: http://msdn.microsoft.com/en-us/library/asx0thw2.aspx  

    If you need use an unmanaged struct, you need this method: http://msdn.microsoft.com/en-us/library/xe5904c9.aspx  

    >>Free the unmanaged resource

    Try this method: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.release.aspx  

    And this one: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject.aspx  

    and here is an topic about clean up unmanaged resource: http://msdn.microsoft.com/en-us/library/498928w2.aspx 

    I hope it will be helpful.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, April 22, 2013 6:11 AM
  • [...]

    Am I on the right track, and if so, how do I:

    Allocate the unmanaged resource

    and

    Free the unmanaged resource

    to clear the error message?


    I think that this is already done somewhere in your code. Find the places that initialize deviceHandle and winUsbHandle.

    The code analysis warning probably suggests that you should make your DeviceInfo disposable, i.e. ‘class DeviceInfo : IDisposable’. Then add the code the frees deviceHandle and winUsbHandle. This depends on how these values were created. If this is already done outside the class, then move the fragments to Dispose.


    • Proposed as answer by Mike Feng Thursday, April 25, 2013 10:26 AM
    Monday, April 22, 2013 6:16 AM
  • Mike,

    I tried to marshal the _myDeviceInfo object using:

    WinUsbCommunications.UnmanagedResources.DeviceInfo myDeviceInfo_unmarshaled =
    new WinUsbCommunications.UnmanagedResources.DeviceInfo();
    IntPtr pnt = 
    Marshal.AllocHGlobal(Marshal.SizeOf(myDeviceInfo_unmarshaled ));
    Marshal.StructureToPtr(myDeviceInfo_unmarshaled, pnt, false);   
     _myDeviceInfo = (WinUsbCommunications.UnmanagedResources.DeviceInfo)Marshal.PtrToStructure(pnt, typeof(WinUsbCommunications.UnmanagedResources.DeviceInfo));
    but the first line gives the error:

    cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

    I get the same error even if I remove the IntPtr and SafeFileHandle from DeviceInfo.
    Tuesday, April 23, 2013 5:33 PM
  • Viorel,

    It's only deviceHandle that causes the error, not WinUsbHandle.

    The DeviceInfo class is defined in the WinUsbCommunications class. The _myDeviceInfo object is defined in the frmMain class. Thus I'm not clear on how to use Dispose in the DeviceInfo class to dispose of the _myDeviceInfo object.

    This is the definition of _myDeviceInfo:

    private WinUsbCommunications.UnmanagedResources.DeviceInfo _myDeviceInfo = 
    new WinUsbCommunications.UnmanagedResources.DeviceInfo();
    If I remove WinUsbHandle from the DeviceInfo class, I get no errors. This means that routines in frmMain must pass two parameters (WinUsbHandle and myDeviceInfo) instead of one (myDeviceInfo) to many functions in WinUsbCommunications. But maybe that's the easiest way to handle this.
    • Marked as answer by Jan Axelson Monday, April 29, 2013 3:07 PM
    Tuesday, April 23, 2013 5:33 PM
  • Mike,

    I tried to marshal the _myDeviceInfo object using:

    WinUsbCommunications.UnmanagedResources.DeviceInfo myDeviceInfo_unmarshaled =
    new WinUsbCommunications.UnmanagedResources.DeviceInfo();
    IntPtr pnt = 
    Marshal.AllocHGlobal(Marshal.SizeOf(myDeviceInfo_unmarshaled ));
    Marshal.StructureToPtr(myDeviceInfo_unmarshaled, pnt, false);   
     _myDeviceInfo = (WinUsbCommunications.UnmanagedResources.DeviceInfo)Marshal.PtrToStructure(pnt, typeof(WinUsbCommunications.UnmanagedResources.DeviceInfo));
    but the first line gives the error:

    cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

    I get the same error even if I remove the IntPtr and SafeFileHandle from DeviceInfo.

    Hi Jan,

    myDeviceInfo_unmarshaled has already be allocated resource. You don't need to alloc memory for it again.

    Here, I would like suggest you try Viorel's suggest.

    The type WinUsbCommunications.UnmanagedResources.DeviceInfo is a custom type, right? So you can implement the dispose method to release the resource. As Viorel suggested, if your application can work welll, the resource should be release somewhere, you can just put that code in the dispose method. Of course, you need to implement the Idispose interface.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, April 24, 2013 2:46 AM