Let\'s look at the following snippet which shows the problem.
class Program
{
static void Main(string[] args)
{
var task = Start();
T
You think that you are still reference to Synchronizer, because you assume that your TaskCompletionSource is still reference to the Synchronizer and your TaskCompletionSource is still "alive" (referenced by GC roots). One of these assumption is not right.
Now, forget about your TaskCompletionSource
replace the line
return tcs.Task;
by for example
return Task.Run(() => { while (true) { } });
then you won't enter the Destructor ever again.
The conclusion is that: If you want to make sure that a object won't be garbage collected, then you will have to explicitly make a strong reference to it. Don't assume that a object is "safe" because it is referenced by something not in your control.