Changed RedisSubscriber wait with TaskCondition vs Timers

This update provides stability and performance improvements to the `RedisSubscriber`:

- Uses `TaskCondition` notifications rather than rearming timers throughout the class.

- Permits queuing actions in case multiple tasks are communicating, the old Timer/null check method had undefined behavior.

- Fixes an error with the `ConnectionPool`, where connections could be re-used after they were closed. An assertion on the new event driver required this fix.
The mutex doesn't *protect* the condition variable, it's more that the condition variable has a feature that it can perform the unlock-wait and trigger-lock steps atomically from the view of code that runs within a region locked by the mutex. This makes a loop like this thread-safe:

```
bool condition;
Mutex mutex;
Condition conditionVar;

synchronized (mutex) {
    while (!condition)
        conditionVar.wait();
    assert(condition); // only guaranteed for the mutex passed to the condition variable!
}
```

Using the condition variable itself would be perfectly fine without the mutex.