2 // CancellationTokenSourceTest.cs
5 // Marek Safar (marek.safar@gmail.com)
6 // Jeremie Laval (jeremie.laval@gmail.com)
8 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Threading;
34 using NUnit.Framework;
35 using System.Threading.Tasks;
37 namespace MonoTests.System.Threading
40 public class CancellationTokenSourceTest
45 public void Ctor_Invalid ()
48 new CancellationTokenSource (-4);
50 } catch (ArgumentException) {
55 public void Ctor_Timeout ()
58 var cts = new CancellationTokenSource (TimeSpan.FromMilliseconds (20));
59 cts.Token.Register (() => called++);
61 Assert.AreEqual (1, called, "#1");
65 public void CancelAfter ()
68 var cts = new CancellationTokenSource ();
69 cts.Token.Register (() => called++);
72 Assert.AreEqual (1, called, "#1");
76 public void CancelAfter_Invalid ()
78 var cts = new CancellationTokenSource ();
82 } catch (ArgumentException) {
87 public void CancelAfter_Disposed ()
90 var cts = new CancellationTokenSource ();
91 cts.Token.Register (() => called++);
95 Assert.AreEqual (0, called, "#1");
103 CancellationTokenSource cts = new CancellationTokenSource ();
104 Assert.IsTrue (cts.Token.CanBeCanceled, "#1");
105 Assert.IsFalse (cts.Token.IsCancellationRequested, "#2");
106 Assert.IsNotNull (cts.Token.WaitHandle, "#3");
110 public void Cancel_NoRegistration ()
112 CancellationTokenSource cts = new CancellationTokenSource ();
117 public void Cancel ()
119 var cts = new CancellationTokenSource ();
122 cts.Token.Register (l => { Assert.AreEqual ("v", l); ++called; }, "v");
124 Assert.AreEqual (1, called, "#1");
127 cts.Token.Register (() => { called += 12; });
129 Assert.AreEqual (12, called, "#2");
134 public void CancelWithDispose ()
136 CancellationTokenSource cts = new CancellationTokenSource ();
137 CancellationToken c = cts.Token;
148 Assert.AreEqual (1, called, "#1");
152 public void Cancel_SingleException ()
154 var cts = new CancellationTokenSource ();
156 cts.Token.Register (() => { throw new ApplicationException (); });
160 } catch (AggregateException e) {
161 Assert.AreEqual (1, e.InnerExceptions.Count, "#2");
168 public void Cancel_MultipleExceptions ()
170 var cts = new CancellationTokenSource ();
172 cts.Token.Register (() => { throw new ApplicationException ("1"); });
173 cts.Token.Register (() => { throw new ApplicationException ("2"); });
174 cts.Token.Register (() => { throw new ApplicationException ("3"); });
179 } catch (AggregateException e) {
180 Assert.AreEqual (3, e.InnerExceptions.Count, "#2");
186 cts.Token.Register (() => { throw new ApplicationException ("1"); });
188 } catch (ApplicationException) {
195 public void Cancel_MultipleException_Recursive ()
197 CancellationTokenSource cts = new CancellationTokenSource ();
198 CancellationToken c = cts.Token;
204 throw new ApplicationException ();
208 throw new NotSupportedException ();
214 } catch (AggregateException e) {
215 Assert.AreEqual (2, e.InnerExceptions.Count, "#2");
220 public void Cancel_MultipleExceptionsFirstThrows ()
222 var cts = new CancellationTokenSource ();
224 cts.Token.Register (() => { throw new ApplicationException ("1"); });
225 cts.Token.Register (() => { throw new ApplicationException ("2"); });
226 cts.Token.Register (() => { throw new ApplicationException ("3"); });
231 } catch (ApplicationException) {
238 public void CreateLinkedTokenSource_InvalidArguments ()
240 var cts = new CancellationTokenSource ();
241 var token = cts.Token;
244 CancellationTokenSource.CreateLinkedTokenSource (null);
246 } catch (ArgumentNullException) {
250 CancellationTokenSource.CreateLinkedTokenSource (new CancellationToken[0]);
252 } catch (ArgumentException) {
257 public void CreateLinkedTokenSource ()
259 var cts = new CancellationTokenSource ();
262 var linked = CancellationTokenSource.CreateLinkedTokenSource (cts.Token);
263 Assert.IsTrue (linked.IsCancellationRequested, "#1");
265 linked = CancellationTokenSource.CreateLinkedTokenSource (new CancellationToken ());
266 Assert.IsFalse (linked.IsCancellationRequested, "#2");
270 public void Dispose ()
272 var cts = new CancellationTokenSource ();
273 var token = cts.Token;
277 var b = cts.IsCancellationRequested;
278 token.ThrowIfCancellationRequested ();
283 } catch (ObjectDisposedException) {
289 } catch (ObjectDisposedException) {
293 token.Register (() => { });
295 } catch (ObjectDisposedException) {
299 var wh = token.WaitHandle;
301 } catch (ObjectDisposedException) {
305 CancellationTokenSource.CreateLinkedTokenSource (token);
307 } catch (ObjectDisposedException) {
314 } catch (ObjectDisposedException) {
320 public void RegisterThenDispose ()
322 var cts1 = new CancellationTokenSource ();
323 var reg1 = cts1.Token.Register (() => { throw new ApplicationException (); });
325 var cts2 = new CancellationTokenSource ();
326 var reg2 = cts2.Token.Register (() => { throw new ApplicationException (); });
328 Assert.AreNotEqual (cts1, cts2, "#1");
329 Assert.AreNotSame (cts1, cts2, "#2");
337 } catch (AggregateException) {
342 public void RegisterWhileCancelling ()
344 var cts = new CancellationTokenSource ();
345 var mre = new ManualResetEvent (false);
346 var mre2 = new ManualResetEvent (false);
349 cts.Token.Register (() => {
350 Assert.IsTrue (cts.IsCancellationRequested, "#10");
351 Assert.IsTrue (cts.Token.WaitHandle.WaitOne (0), "#11");
357 var t = Task.Factory.StartNew (() => { cts.Cancel (); });
359 Assert.IsTrue (mre2.WaitOne (1000), "#0");
360 cts.Token.Register (() => { called++; });
361 Assert.AreEqual (1, called, "#1");
362 Assert.IsFalse (t.IsCompleted, "#2");
365 Assert.IsTrue (t.Wait (1000), "#3");
366 Assert.AreEqual (12, called, "#4");
370 public void ReEntrantRegistrationTest ()
372 bool unregister = false;
373 bool register = false;
374 var source = new CancellationTokenSource ();
375 var token = source.Token;
377 var reg = new CancellationTokenRegistration ();
378 Console.WriteLine ("Test1");
379 token.Register (() => reg.Dispose ());
380 reg = token.Register (() => unregister = true);
381 token.Register (() => { Console.WriteLine ("Gnyah"); token.Register (() => register = true); });
384 Assert.IsFalse (unregister);
385 Assert.IsTrue (register);
389 public void DisposeAfterRegistrationTest ()
391 var source = new CancellationTokenSource ();
393 var req = source.Token.Register (() => ran = true);
396 Assert.IsFalse (ran);