Add Adapter.DeviceConnected / DeviceDisconnected events - #81
Conversation
…g-replay handlers
TrackDeviceForConnection reserves a dictionary slot with a null sentinel before awaiting Device.CreateAsync. Dispose iterated the values without a null check, so disposing while a reservation was pending threw a NullReferenceException. Reaching Dispose from the finalizer made that exception kill the process, and it aborted the remaining teardown after the signal watchers had been disposed, leaving the adapter unable to receive InterfacesAdded.
|
Pushed two follow-up fixes found while running this on hardware: 1. Exceptions escaping the new signal handlers. 2. |
Details
AdapterexposesDeviceFoundfor device discovery, but there is no equivalent event for a device's connection state. To learn that a device connected, a caller must enumerate devices itself and wire up eachDevice's per-deviceConnectedwatch — and even then it can miss connections (see below).This PR adds two adapter-level events as the connection-side twin of
DeviceFound:event DeviceChangeEventHandlerAsync DeviceConnectedevent DeviceChangeEventHandlerAsync DeviceDisconnectedThey fire for any device transitioning to/from connected, regardless of how its
Device1object came to exist.De-duplication
Device.Connectedcan fire twice for one transition — once from the add-accessor replay (FireEventIfPropertyAlreadyTrueAsync) and once from the livePropertiesChanged. (There is an existing// TODO: Suppress duplicate event from OnPropertyChangesat that spot.) The adapter tracks per-device connected state and relays only on an actual edge, soDeviceConnected/ DeviceDisconnected` fire exactly once per transition.Design notes
DeviceFoundevent pattern (add-accessor bootstrap,DeviceFoundEventArgscarrying theDevice).Interlockedso concurrentPropertiesChangedcallbacks can't double-fire.netstandard2.0-compatible (noDictionary.Remove(key, out value)overload).Usage