The DisconnectTaskCompletionSource is created when the Connection is instantiated, but it is only ever observed when WaitForDisconnect is called (which returns the Task). When DisconnectTaskCompletionSource is finalized after the Connection is torn down, the task scheduler throws an UnobservedTaskException, which we can see in slskd if we turn on logging of these exceptions.
Think of a refactor that avoids creating this instance of TaskCompletionSource unless it's actually going to be used. Within the WaitForDisconnect method might be a good option.
There's a related issue in WaitForDisconnect as well; calling cancellationToken?.Register() creates a CancellationTokenRegistration object that is IDisposable but never gets disposed. This should be assigned to a property and disposed along with other class members.
The
DisconnectTaskCompletionSourceis created when theConnectionis instantiated, but it is only ever observed whenWaitForDisconnectis called (which returns theTask). WhenDisconnectTaskCompletionSourceis finalized after theConnectionis torn down, the task scheduler throws anUnobservedTaskException, which we can see in slskd if we turn on logging of these exceptions.Think of a refactor that avoids creating this instance of
TaskCompletionSourceunless it's actually going to be used. Within theWaitForDisconnectmethod might be a good option.There's a related issue in
WaitForDisconnectas well; callingcancellationToken?.Register()creates aCancellationTokenRegistrationobject that isIDisposablebut never gets disposed. This should be assigned to a property and disposed along with other class members.