1

Perhaps my question shows a lack of understanding in how IDisposible works, but I have a collection of class objects that manage communication with HID devices, each type has its own logic for detecting when the HID device is no longer active or communicating and will dispose of itself, but I would also like the class object to be removed from my ObservableCollection that stores all of them on its disposal.

Since this is a threaded environment im having a hard time picturing a way to implement a solution that wouldn't face race conditions.

Google so far has only yielded solutions to the opposite situation (dispose an object on removal from list).

Is it as simple as this?

    #region IDisposable Support
    private bool disposedValue = false; // To detect redundant calls

    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                _hdevice.CancelIO();
                _hdevice.CloseDevice();
                _hdevice.Dispose();
            }

            // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
            // TODO: set large fields to null.

            //Remove device from its collection
            lock (DeviceEnumerator.Devices)
            {
                DeviceEnumerator.Devices.Remove(this);
            }

            disposedValue = true;
        }
    }

    // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
    // ~Dualshock4() {
    //   // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
    //   Dispose(false);
    // }

    // This code added to correctly implement the disposable pattern.
    public void Dispose()
    {
        // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
        Dispose(true);
        // TODO: uncomment the following line if the finalizer is overridden above.
        // GC.SuppressFinalize(this);
    }
    #endregion
Codor
  • 17,447
  • 9
  • 29
  • 56
Wobbles
  • 3,033
  • 1
  • 25
  • 51
  • 2
    I guess the IDisposable would need a reference to the ObservableCollection it is contained in, then Dispose() can call Remove(this) – Sentry Oct 22 '16 at 18:36
  • @Sentry thats what I think aswell (edited to post sample above) but I see no protection from race conditions resulting in null references here. – Wobbles Oct 22 '16 at 18:38
  • Winforms uses [`IComponent`](https://msdn.microsoft.com/en-us/library/system.componentmodel.icomponent(v=vs.110).aspx) do this kind of logic. The `ISite` object points to the container that the component is held in and in your dispose logic you can remove yourself from the parent collection. – Scott Chamberlain Oct 22 '16 at 19:10
  • @ScottChamberlain - but WinForms is always single-threaded. – H H Oct 22 '16 at 20:42
  • @Wobbles - you should [make the Observable thread-safe](http://stackoverflow.com/q/23108045) and I would move that part up, before _hedvice stuff. If you then still have race-conditions then you have some logic problems beyond this scope. – H H Oct 22 '16 at 20:46

1 Answers1

1

The issue with your solution is that each device object needs a reference to the collection, which increases coupling.

A more decoupled solution would be to implement a Disposed event that is raised from the Dispose method. You would subscribe to the event when you add an device to the collection, and remove the device from the collection when the event is raised.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • Well refrencing the collection in my instance is easy enough because it is contained as a static observable collection and easily accessible. The idea of a disposing event is interesting tho – Wobbles Oct 22 '16 at 18:46
  • Just because it's easy doesn't mean it's right ;). You should try to keep your components as independent as possible from each other. It might seem more difficult, but in the long run it will make maintenance and evolutions easier. – Thomas Levesque Oct 22 '16 at 20:41
  • So i actually started to write my own reusable `INotifyDisposed` interface and thought of somthing, how is a parent object supposed to hook the `MyObj.Disposed` event if `MyObj` is disposed? Seems the best I can do if I want to be strict about my terminology is `Disposing`. – Wobbles Oct 23 '16 at 13:28