Mercurial > pub > ImplabNet
annotate Implab.Test/AsyncTests.cs @ 121:62d2f1e98c4e v2
working version of AsyncQueue and batch operations
tests
author | cin |
---|---|
date | Mon, 12 Jan 2015 18:19:41 +0300 |
parents | 2573b562e328 |
children | 0c8685c8b56b |
rev | line source |
---|---|
77 | 1 using System; |
2 using System.Reflection; | |
3 using System.Threading; | |
4 using Implab.Parallels; | |
5 | |
6 #if MONO | |
7 | |
8 using NUnit.Framework; | |
9 using TestClassAttribute = NUnit.Framework.TestFixtureAttribute; | |
10 using TestMethod = NUnit.Framework.TestAttribute; | |
11 | |
12 #else | |
13 | |
14 using Microsoft.VisualStudio.TestTools.UnitTesting; | |
15 | |
16 #endif | |
17 | |
18 namespace Implab.Test { | |
19 [TestClass] | |
20 public class AsyncTests { | |
21 [TestMethod] | |
22 public void ResolveTest() { | |
23 int res = -1; | |
24 var p = new Promise<int>(); | |
25 p.Then(x => res = x); | |
26 p.Resolve(100); | |
27 | |
28 Assert.AreEqual(100, res); | |
29 } | |
30 | |
31 [TestMethod] | |
32 public void RejectTest() { | |
33 int res = -1; | |
34 Exception err = null; | |
35 | |
36 var p = new Promise<int>(); | |
37 p.Then( | |
38 x => res = x, | |
39 e => { | |
40 err = e; | |
41 return -2; | |
42 } | |
43 ); | |
44 p.Reject(new ApplicationException("error")); | |
45 | |
46 Assert.AreEqual(res, -1); | |
47 Assert.AreEqual(err.Message, "error"); | |
48 | |
49 } | |
50 | |
51 [TestMethod] | |
52 public void CancelExceptionTest() { | |
53 var p = new Promise<bool>(); | |
54 p.Cancel(); | |
55 | |
56 var p2 = p.Cancelled(() => { | |
57 throw new ApplicationException("CANCELLED"); | |
58 }); | |
59 | |
60 try { | |
61 p2.Join(); | |
62 Assert.Fail(); | |
63 } catch (ApplicationException err) { | |
64 Assert.AreEqual("CANCELLED", err.InnerException.Message); | |
65 } | |
66 | |
67 } | |
68 | |
69 [TestMethod] | |
70 public void ContinueOnCancelTest() { | |
71 var p = new Promise<bool>(); | |
72 p.Cancel(); | |
73 | |
74 var p2 = p | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
75 .Cancelled<bool>(() => { |
77 | 76 throw new ApplicationException("CANCELLED"); |
77 }) | |
78 .Error(e => true); | |
79 | |
80 Assert.AreEqual(true, p2.Join()); | |
81 } | |
82 | |
83 [TestMethod] | |
84 public void JoinSuccessTest() { | |
85 var p = new Promise<int>(); | |
86 p.Resolve(100); | |
87 Assert.AreEqual(p.Join(), 100); | |
88 } | |
89 | |
90 [TestMethod] | |
91 public void JoinFailTest() { | |
92 var p = new Promise<int>(); | |
93 p.Reject(new ApplicationException("failed")); | |
94 | |
95 try { | |
96 p.Join(); | |
97 throw new ApplicationException("WRONG!"); | |
98 } catch (TargetInvocationException err) { | |
99 Assert.AreEqual(err.InnerException.Message, "failed"); | |
100 } catch { | |
101 Assert.Fail("Got wrong excaption"); | |
102 } | |
103 } | |
104 | |
105 [TestMethod] | |
106 public void MapTest() { | |
107 var p = new Promise<int>(); | |
108 | |
109 var p2 = p.Then(x => x.ToString()); | |
110 p.Resolve(100); | |
111 | |
112 Assert.AreEqual(p2.Join(), "100"); | |
113 } | |
114 | |
115 [TestMethod] | |
116 public void FixErrorTest() { | |
117 var p = new Promise<int>(); | |
118 | |
119 var p2 = p.Error(e => 101); | |
120 | |
121 p.Reject(new Exception()); | |
122 | |
123 Assert.AreEqual(p2.Join(), 101); | |
124 } | |
125 | |
126 [TestMethod] | |
127 public void ChainTest() { | |
128 var p1 = new Promise<int>(); | |
129 | |
130 var p3 = p1.Chain(x => { | |
131 var p2 = new Promise<string>(); | |
132 p2.Resolve(x.ToString()); | |
133 return p2; | |
134 }); | |
135 | |
136 p1.Resolve(100); | |
137 | |
138 Assert.AreEqual(p3.Join(), "100"); | |
139 } | |
140 | |
141 [TestMethod] | |
105 | 142 public void ChainFailTest() { |
143 var p1 = new Promise<int>(); | |
144 | |
145 var p3 = p1.Chain(x => { | |
146 var p2 = new Promise<string>(); | |
147 p2.Reject(new Exception("DIE!!!")); | |
148 return p2; | |
149 }); | |
150 | |
151 p1.Resolve(100); | |
152 | |
153 Assert.IsTrue(p3.IsResolved); | |
154 } | |
155 | |
156 [TestMethod] | |
77 | 157 public void PoolTest() { |
158 var pid = Thread.CurrentThread.ManagedThreadId; | |
159 var p = AsyncPool.Invoke(() => Thread.CurrentThread.ManagedThreadId); | |
160 | |
161 Assert.AreNotEqual(pid, p.Join()); | |
162 } | |
163 | |
164 [TestMethod] | |
165 public void WorkerPoolSizeTest() { | |
81 | 166 var pool = new WorkerPool(5, 10, 1); |
77 | 167 |
168 Assert.AreEqual(5, pool.PoolSize); | |
169 | |
170 pool.Invoke(() => { Thread.Sleep(100000000); return 10; }); | |
171 pool.Invoke(() => { Thread.Sleep(100000000); return 10; }); | |
172 pool.Invoke(() => { Thread.Sleep(100000000); return 10; }); | |
173 | |
174 Assert.AreEqual(5, pool.PoolSize); | |
175 | |
176 for (int i = 0; i < 100; i++) | |
177 pool.Invoke(() => { Thread.Sleep(100000000); return 10; }); | |
178 Thread.Sleep(200); | |
179 Assert.AreEqual(10, pool.PoolSize); | |
180 | |
181 pool.Dispose(); | |
182 } | |
183 | |
184 [TestMethod] | |
185 public void WorkerPoolCorrectTest() { | |
186 var pool = new WorkerPool(0,1000,100); | |
187 | |
188 const int iterations = 1000; | |
189 int pending = iterations; | |
190 var stop = new ManualResetEvent(false); | |
191 | |
192 var count = 0; | |
193 for (int i = 0; i < iterations; i++) { | |
194 pool | |
195 .Invoke(() => 1) | |
196 .Then(x => Interlocked.Add(ref count, x)) | |
197 .Then(x => Math.Log10(x)) | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
198 .On(() => { |
77 | 199 Interlocked.Decrement(ref pending); |
200 if (pending == 0) | |
201 stop.Set(); | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
202 }, PromiseEventType.All); |
77 | 203 } |
204 | |
205 stop.WaitOne(); | |
206 | |
207 Assert.AreEqual(iterations, count); | |
208 Console.WriteLine("Max threads: {0}", pool.MaxRunningThreads); | |
209 pool.Dispose(); | |
210 | |
211 } | |
212 | |
213 [TestMethod] | |
214 public void WorkerPoolDisposeTest() { | |
215 var pool = new WorkerPool(5, 20); | |
216 Assert.AreEqual(5, pool.PoolSize); | |
217 pool.Dispose(); | |
218 Thread.Sleep(500); | |
219 Assert.AreEqual(0, pool.PoolSize); | |
220 pool.Dispose(); | |
221 } | |
222 | |
223 [TestMethod] | |
224 public void MTQueueTest() { | |
225 var queue = new MTQueue<int>(); | |
226 int res; | |
227 | |
228 queue.Enqueue(10); | |
229 Assert.IsTrue(queue.TryDequeue(out res)); | |
230 Assert.AreEqual(10, res); | |
231 Assert.IsFalse(queue.TryDequeue(out res)); | |
232 | |
233 for (int i = 0; i < 1000; i++) | |
234 queue.Enqueue(i); | |
235 | |
236 for (int i = 0; i < 1000; i++) { | |
237 queue.TryDequeue(out res); | |
238 Assert.AreEqual(i, res); | |
239 } | |
240 | |
241 int writers = 0; | |
242 int readers = 0; | |
243 var stop = new ManualResetEvent(false); | |
244 int total = 0; | |
245 | |
246 const int itemsPerWriter = 10000; | |
247 const int writersCount = 10; | |
248 | |
249 for (int i = 0; i < writersCount; i++) { | |
250 Interlocked.Increment(ref writers); | |
251 AsyncPool | |
252 .InvokeNewThread(() => { | |
253 for (int ii = 0; ii < itemsPerWriter; ii++) { | |
254 queue.Enqueue(1); | |
255 } | |
256 return 1; | |
257 }) | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
258 .On(() => Interlocked.Decrement(ref writers), PromiseEventType.All); |
77 | 259 } |
260 | |
261 for (int i = 0; i < 10; i++) { | |
262 Interlocked.Increment(ref readers); | |
263 AsyncPool | |
264 .InvokeNewThread(() => { | |
265 int t; | |
266 do { | |
267 while (queue.TryDequeue(out t)) | |
268 Interlocked.Add(ref total, t); | |
269 } while (writers > 0); | |
270 return 1; | |
271 }) | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
272 .On(() => { |
77 | 273 Interlocked.Decrement(ref readers); |
274 if (readers == 0) | |
275 stop.Set(); | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
276 }, PromiseEventType.All); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
277 } |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
278 |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
279 stop.WaitOne(); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
280 |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
281 Assert.AreEqual(100000, total); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
282 } |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
283 |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
284 [TestMethod] |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
285 public void AsyncQueueTest() { |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
286 var queue = new AsyncQueue<int>(); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
287 int res; |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
288 |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
289 queue.Enqueue(10); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
290 Assert.IsTrue(queue.TryDequeue(out res)); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
291 Assert.AreEqual(10, res); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
292 Assert.IsFalse(queue.TryDequeue(out res)); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
293 |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
294 for (int i = 0; i < 1000; i++) |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
295 queue.Enqueue(i); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
296 |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
297 for (int i = 0; i < 1000; i++) { |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
298 queue.TryDequeue(out res); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
299 Assert.AreEqual(i, res); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
300 } |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
301 |
121 | 302 const int count = 10000000; |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
303 |
121 | 304 int res1 = 0, res2 = 0; |
305 var t1 = Environment.TickCount; | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
306 |
121 | 307 AsyncPool.RunThread( |
308 () => { | |
309 for (var i = 0; i < count; i++) | |
310 queue.Enqueue(1); | |
311 Console.WriteLine("done writer #1: {0} ms", Environment.TickCount - t1); | |
312 }, | |
313 () => { | |
314 for (var i = 0; i < count; i++) | |
315 queue.Enqueue(2); | |
316 Console.WriteLine("done writer #2: {0} ms", Environment.TickCount - t1); | |
317 }, | |
318 () => { | |
319 int temp; | |
320 int i = 0; | |
321 while (i < count) | |
322 if (queue.TryDequeue(out temp)) { | |
323 i++; | |
324 res1 += temp; | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
325 } |
121 | 326 Console.WriteLine("done reader #1: {0} ms", Environment.TickCount - t1); |
327 }, | |
328 () => { | |
329 int temp; | |
330 int i = 0; | |
331 while (i < count) | |
332 if (queue.TryDequeue(out temp)) { | |
333 i++; | |
334 res2 += temp; | |
335 } | |
336 Console.WriteLine("done reader #2: {0} ms", Environment.TickCount - t1); | |
337 } | |
338 ) | |
339 .Combine() | |
340 .Join(); | |
341 | |
342 Assert.AreEqual(count * 3, res1 + res2); | |
343 | |
344 Console.WriteLine( | |
345 "done: {0} ms, summ#1: {1}, summ#2: {2}, total: {3}, count: {4}", | |
346 Environment.TickCount - t1, | |
347 res1, | |
348 res2, | |
349 res1 + res2, | |
350 count | |
351 ); | |
352 } | |
353 | |
354 [TestMethod] | |
355 public void AsyncQueueBatchTest() { | |
356 var queue = new AsyncQueue<int>(); | |
357 | |
358 const int wBatch = 29; | |
359 const int wCount = 400000; | |
360 const int total = wBatch * wCount * 2; | |
361 const int summ = wBatch * wCount * 3; | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
362 |
121 | 363 int r1 = 0, r2 = 0; |
364 const int rBatch = 111; | |
365 int read = 0; | |
366 | |
367 var t1 = Environment.TickCount; | |
368 | |
369 AsyncPool.RunThread( | |
370 () => { | |
371 var buffer = new int[wBatch]; | |
372 for(int i = 0; i<wBatch; i++) | |
373 buffer[i] = 1; | |
374 | |
375 for(int i =0; i < wCount; i++) | |
376 queue.EnqueueRange(buffer,0,wBatch); | |
377 Console.WriteLine("done writer #1: {0} ms", Environment.TickCount - t1); | |
378 }, | |
379 () => { | |
380 var buffer = new int[wBatch]; | |
381 for(int i = 0; i<wBatch; i++) | |
382 buffer[i] = 2; | |
383 | |
384 for(int i =0; i < wCount; i++) | |
385 queue.EnqueueRange(buffer,0,wBatch); | |
386 Console.WriteLine("done writer #2: {0} ms", Environment.TickCount - t1); | |
387 }, | |
388 () => { | |
389 var buffer = new int[rBatch]; | |
77 | 390 |
121 | 391 while(read < total) { |
392 int actual; | |
393 if (queue.TryDequeueRange(buffer,0,rBatch,out actual)) { | |
394 for(int i=0; i< actual; i++) | |
395 r1 += buffer[i]; | |
396 Interlocked.Add(ref read, actual); | |
397 } | |
398 } | |
399 | |
400 Console.WriteLine("done reader #1: {0} ms", Environment.TickCount - t1); | |
401 }, | |
402 () => { | |
403 var buffer = new int[rBatch]; | |
77 | 404 |
121 | 405 while(read < total) { |
406 int actual; | |
407 if (queue.TryDequeueRange(buffer,0,rBatch,out actual)) { | |
408 for(int i=0; i< actual; i++) | |
409 r2 += buffer[i]; | |
410 Interlocked.Add(ref read, actual); | |
411 } | |
412 } | |
413 | |
414 Console.WriteLine("done reader #2: {0} ms", Environment.TickCount - t1); | |
415 } | |
416 ) | |
417 .Combine() | |
418 .Join(); | |
419 | |
420 Assert.AreEqual(summ , r1 + r2); | |
421 | |
422 Console.WriteLine( | |
423 "done: {0} ms, summ#1: {1}, summ#2: {2}, total: {3}, count: {4}", | |
424 Environment.TickCount - t1, | |
425 r1, | |
426 r2, | |
427 r1 + r2, | |
428 total | |
429 ); | |
77 | 430 } |
431 | |
432 [TestMethod] | |
433 public void ParallelMapTest() { | |
434 | |
435 const int count = 100000; | |
436 | |
437 var args = new double[count]; | |
438 var rand = new Random(); | |
439 | |
440 for (int i = 0; i < count; i++) | |
441 args[i] = rand.NextDouble(); | |
442 | |
443 var t = Environment.TickCount; | |
444 var res = args.ParallelMap(x => Math.Sin(x*x), 4).Join(); | |
445 | |
446 Console.WriteLine("Map complete in {0} ms", Environment.TickCount - t); | |
447 | |
448 t = Environment.TickCount; | |
449 for (int i = 0; i < count; i++) | |
450 Assert.AreEqual(Math.Sin(args[i] * args[i]), res[i]); | |
451 Console.WriteLine("Verified in {0} ms", Environment.TickCount - t); | |
452 } | |
453 | |
454 [TestMethod] | |
455 public void ChainedMapTest() { | |
456 | |
81 | 457 using (var pool = new WorkerPool(0,10,1)) { |
77 | 458 const int count = 10000; |
459 | |
460 var args = new double[count]; | |
461 var rand = new Random(); | |
462 | |
463 for (int i = 0; i < count; i++) | |
464 args[i] = rand.NextDouble(); | |
465 | |
466 var t = Environment.TickCount; | |
467 var res = args | |
468 .ChainedMap( | |
469 // Analysis disable once AccessToDisposedClosure | |
470 x => pool.Invoke( | |
471 () => Math.Sin(x * x) | |
472 ), | |
473 4 | |
474 ) | |
475 .Join(); | |
476 | |
477 Console.WriteLine("Map complete in {0} ms", Environment.TickCount - t); | |
478 | |
479 t = Environment.TickCount; | |
480 for (int i = 0; i < count; i++) | |
481 Assert.AreEqual(Math.Sin(args[i] * args[i]), res[i]); | |
482 Console.WriteLine("Verified in {0} ms", Environment.TickCount - t); | |
483 Console.WriteLine("Max workers: {0}", pool.MaxRunningThreads); | |
484 } | |
485 } | |
486 | |
487 [TestMethod] | |
488 public void ParallelForEachTest() { | |
489 | |
490 const int count = 100000; | |
491 | |
492 var args = new int[count]; | |
493 var rand = new Random(); | |
494 | |
495 for (int i = 0; i < count; i++) | |
496 args[i] = (int)(rand.NextDouble() * 100); | |
497 | |
498 int result = 0; | |
499 | |
500 var t = Environment.TickCount; | |
501 args.ParallelForEach(x => Interlocked.Add(ref result, x), 4).Join(); | |
502 | |
503 Console.WriteLine("Iteration complete in {0} ms, result: {1}", Environment.TickCount - t, result); | |
504 | |
505 int result2 = 0; | |
506 | |
507 t = Environment.TickCount; | |
508 for (int i = 0; i < count; i++) | |
509 result2 += args[i]; | |
510 Assert.AreEqual(result2, result); | |
511 Console.WriteLine("Verified in {0} ms", Environment.TickCount - t); | |
512 } | |
513 | |
514 [TestMethod] | |
515 public void ComplexCase1Test() { | |
516 var flags = new bool[3]; | |
517 | |
518 // op1 (aync 200ms) => op2 (async 200ms) => op3 (sync map) | |
519 | |
520 var step1 = PromiseHelper | |
521 .Sleep(200, "Alan") | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
522 .On(() => flags[0] = true, PromiseEventType.Cancelled); |
77 | 523 var p = step1 |
524 .Chain(x => | |
525 PromiseHelper | |
526 .Sleep(200, "Hi, " + x) | |
527 .Then(y => y) | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
528 .On(() => flags[1] = true, PromiseEventType.Cancelled) |
77 | 529 ) |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
106
diff
changeset
|
530 .On(() => flags[2] = true, PromiseEventType.Cancelled); |
77 | 531 step1.Join(); |
532 p.Cancel(); | |
533 try { | |
534 Assert.AreEqual(p.Join(), "Hi, Alan"); | |
535 Assert.Fail("Shouldn't get here"); | |
536 } catch (OperationCanceledException) { | |
537 } | |
538 | |
539 Assert.IsFalse(flags[0]); | |
540 Assert.IsTrue(flags[1]); | |
541 Assert.IsTrue(flags[2]); | |
542 } | |
543 | |
544 [TestMethod] | |
545 public void ChainedCancel1Test() { | |
546 // при отмене сцепленной асинхронной операции все обещание должно | |
547 // завершаться ошибкой OperationCanceledException | |
548 var p = PromiseHelper | |
549 .Sleep(1, "Hi, HAL!") | |
550 .Then(x => { | |
551 // запускаем две асинхронные операции | |
552 var result = PromiseHelper.Sleep(1000, "HEM ENABLED!!!"); | |
553 // вторая операция отменяет первую до завершения | |
554 PromiseHelper | |
555 .Sleep(100, "HAL, STOP!") | |
556 .Then(result.Cancel); | |
557 return result; | |
558 }); | |
559 try { | |
560 p.Join(); | |
561 } catch (TargetInvocationException err) { | |
562 Assert.IsTrue(err.InnerException is OperationCanceledException); | |
563 } | |
564 } | |
565 | |
566 [TestMethod] | |
567 public void ChainedCancel2Test() { | |
568 // при отмене цепочки обещаний, вложенные операции также должны отменяться | |
569 var pSurvive = new Promise<bool>(); | |
570 var hemStarted = new ManualResetEvent(false); | |
571 var p = PromiseHelper | |
572 .Sleep(1, "Hi, HAL!") | |
573 .Chain(x => { | |
574 hemStarted.Set(); | |
575 // запускаем две асинхронные операции | |
576 var result = PromiseHelper | |
106 | 577 .Sleep(100000000, "HEM ENABLED!!!") |
578 .Then(s => { | |
579 pSurvive.Resolve(false); | |
580 return s; | |
581 }); | |
77 | 582 |
583 result | |
584 .Cancelled(() => pSurvive.Resolve(true)); | |
585 | |
586 return result; | |
587 }); | |
588 | |
589 hemStarted.WaitOne(); | |
590 p.Cancel(); | |
591 | |
592 try { | |
593 p.Join(); | |
594 } catch (OperationCanceledException) { | |
595 Assert.IsTrue(pSurvive.Join()); | |
596 } | |
597 } | |
598 } | |
599 } | |
600 |