Timer is implemented with internal queue. If a user wants to cancel all pending tasks it can call .cancel to schedule CancelNotification. As a part of processing of CancelNotification it will just flush the whole queue. It does have special processing for StopNotification so that Timer destruction doesn't get blocked. Now if we first schedule async cancel and before this first cancel is processed we schedule another cancel but this time a sync second one will block because it is never notified that all tasks are canceled, _finished event is never set on that flushed CancelNotification.
Timer is implemented with internal queue. If a user wants to cancel all pending tasks it can call .cancel to schedule CancelNotification. As a part of processing of CancelNotification it will just flush the whole queue. It does have special processing for StopNotification so that Timer destruction doesn't get blocked. Now if we first schedule async cancel and before this first cancel is processed we schedule another cancel but this time a sync second one will block because it is never notified that all tasks are canceled, _finished event is never set on that flushed CancelNotification.