Carefully destroy channels at the right time.

When a channel is destroyed, it may attempt scheduler operations which could
move a task off of it's I/O scheduler. This is obviously a bad interaction, and
some finesse is required to make it work (making destructors run at the right
time).

Closes #10375
Fix usage of libuv for windows