Detect slow callbacks in .NET client receive queue and trigger an error

Since we serialize the invocations of Received callbacks in the .NET client,
there is a real risk of deadlocks resulting from one callback blocking waiting
on another callback to execute.

This commit introduces a TaskQueueMonitor used exclusively by the .NET client
to try to detect callbacks that are running long and notify the user using
Connection.OnError that a callback may be deadlocked.

The amount of time a callback may execute before an error is raised can be
configured using Connection.DeadlockErrorTimeout. The default timeout is
10 seconds.

#3167
It does allow me to avoid that silly `protected virtual void Dispose(bool disposing)` pattern. :smile: