Fix dispose race condition in CancellationTokenSource
The race condition would manifest in the following code:
```
for (int i = 0, total = 100000; i < total; ++i) {
if (i % 50 == 0)
Console.WriteLine ("{0}/{1}", i, total);
var c1 = new CancellationTokenSource ();
var wh = c1.Token.WaitHandle;
c1.CancelAfter (1);
Thread.Sleep (1);
c1.Dispose ();
}
```
And we would observe the following exception:
```
Unhandled Exception: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Threading.ManualResetEvent'.
at System.Threading.WaitHandle.CheckDisposed () [0x00016] in /Users/builder/data/lanes/1196/
33e00ac6/source/mono/mcs/class/corlib/System.Threading/WaitHandle.cs:426
at System.Threading.EventWaitHandle.Set () [0x0000c] in /Users/builder/data/lanes/1196/
33e00ac6/source/mono/mcs/class/corlib/System.Threading/EventWaitHandle.cs:205
at (wrapper remoting-invoke-with-check) System.Threading.EventWaitHandle:Set ()
at System.Threading.CancellationTokenSource.NotifyCancellation (Boolean throwOnFirstException) [0x00051] in /Users/builder/data/lanes/1196/
33e00ac6/source/mono/external/referencesource/mscorlib/system/threading/CancellationTokenSource.cs:723
at System.Threading.CancellationTokenSource.Cancel (Boolean throwOnFirstException) [0x00006] in /Users/builder/data/lanes/1196/
33e00ac6/source/mono/external/referencesource/mscorlib/system/threading/CancellationTokenSource.cs:409
at System.Threading.CancellationTokenSource.Cancel () <0x7d75ada8 + 0x00017> in <filename unknown>:0
at System.Threading.CancellationTokenSource.TimerCallbackLogic (System.Object obj) [0x00012] in /Users/builder/data/lanes/1196/
33e00ac6/source/mono/external/referencesource/mscorlib/system/threading/CancellationTokenSource.cs:538
```
This would be a race condition between the TimerCallbackLogic call to Cancel and the call to Dispose on another thread. You could trigger it more reliably by putting a Thread.Sleep at CancellationTokenSource.cs:599.