1 // ThreadTest.cs - NUnit Test Cases for the System.Threading.Thread class 2 // 3 // Authors 4 // Eduardo Garcia Cebollero (kiwnix@yahoo.es) 5 // Sebastien Pouliot <sebastien@ximian.com> 6 // 7 // (C) Eduardo Garcia Cebollero. 8 // (C) Ximian, Inc. http://www.ximian.com 9 // (C) 2004 Novell (http://www.novell.com) 10 // 11 12 using System; 13 using System.Globalization; 14 using System.Security.Principal; 15 using System.Threading; 16 using System.Threading.Tasks; 17 using System.Reflection; 18 using System.Collections.Generic; 19 using SD = System.Diagnostics; 20 21 using NUnit.Framework; 22 23 namespace MonoTests.System.Threading 24 { 25 // These tests seem to hang the 2.0 framework. So they are disabled for now 26 // Don't reenable them until you can run a few thousand times on an SMP box. 27 [Category ("NotWorking")] 28 public class ThreadedPrincipalTest 29 { NoPrincipal()30 public static void NoPrincipal () 31 { 32 AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.NoPrincipal); 33 IPrincipal p = Thread.CurrentPrincipal; 34 Assert.IsNull (p, "#1"); 35 36 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null); 37 Assert.IsNotNull (Thread.CurrentPrincipal, "#2"); 38 39 Thread.CurrentPrincipal = null; 40 Assert.IsNull (Thread.CurrentPrincipal, "#3"); 41 // in this case we can return to null 42 } 43 UnauthenticatedPrincipal()44 public static void UnauthenticatedPrincipal () 45 { 46 AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.UnauthenticatedPrincipal); 47 IPrincipal p = Thread.CurrentPrincipal; 48 Assert.IsNotNull (p, "#1"); 49 Assert.IsTrue ((p is GenericPrincipal), "#2"); 50 Assert.AreEqual (String.Empty, p.Identity.Name, "#3"); 51 Assert.AreEqual (String.Empty, p.Identity.AuthenticationType, "#4"); 52 Assert.IsFalse (p.Identity.IsAuthenticated, "#5"); 53 54 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null); 55 Assert.IsNotNull (Thread.CurrentPrincipal, "#6"); 56 57 Thread.CurrentPrincipal = null; 58 Assert.IsNotNull (Thread.CurrentPrincipal, "#7"); 59 // in this case we can't return to null 60 } 61 WindowsPrincipal()62 public static void WindowsPrincipal () 63 { 64 AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.WindowsPrincipal); 65 IPrincipal p = Thread.CurrentPrincipal; 66 Assert.IsNotNull (p, "#1"); 67 Assert.IsTrue ((p is WindowsPrincipal), "#2"); 68 Assert.IsNotNull (p.Identity.Name, "#3"); 69 Assert.IsNotNull (p.Identity.AuthenticationType, "#4"); 70 Assert.IsTrue (p.Identity.IsAuthenticated, "#5"); 71 72 // note: we can switch from a WindowsPrincipal to a GenericPrincipal 73 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null); 74 Assert.IsNotNull (Thread.CurrentPrincipal, "#6"); 75 76 Thread.CurrentPrincipal = null; 77 Assert.IsNotNull (Thread.CurrentPrincipal, "#7"); 78 // in this case we can't return to null 79 } 80 CopyOnNewThread()81 public static void CopyOnNewThread () 82 { 83 Assert.IsNotNull (Thread.CurrentPrincipal, "#1"); 84 Assert.AreEqual ("good", Thread.CurrentPrincipal.Identity.Name, "#2"); 85 } 86 } 87 88 [TestFixture] 89 [Category("MobileNotWorking")] // Abort #10240 90 public class ThreadTest 91 { 92 //TimeSpan Infinite = new TimeSpan (-10000); // -10000 ticks == -1 ms 93 TimeSpan SmallNegative = new TimeSpan (-2); // between 0 and -1.0 (infinite) ms 94 TimeSpan Negative = new TimeSpan (-20000); // really negative 95 //TimeSpan MaxValue = TimeSpan.FromMilliseconds ((long) Int32.MaxValue); 96 TimeSpan TooLarge = TimeSpan.FromMilliseconds ((long) Int32.MaxValue + 1); 97 98 //Some Classes to test as threads 99 private class C1Test 100 { 101 public int cnt; 102 public Thread thread1; 103 public bool endm1; 104 public bool endm2; 105 C1Test()106 public C1Test() 107 { 108 thread1 = (Thread)null; 109 this.cnt = 0; 110 endm1 = endm2 = false; 111 } 112 TestMethod()113 public void TestMethod() 114 { 115 while (cnt < 10) 116 { 117 cnt++; 118 } 119 endm1 = true; 120 } TestMethod2()121 public void TestMethod2() 122 { 123 if (!(thread1==(Thread)null) ) 124 { 125 thread1.Join(); 126 } 127 endm2 = true; 128 } 129 } 130 131 private class C2Test 132 { 133 public int cnt; 134 public bool run = false; 135 C2Test()136 public C2Test() 137 { 138 this.cnt = 0; 139 } 140 TestMethod()141 public void TestMethod() 142 { 143 run = true; 144 while (true) 145 { 146 if (cnt < 1000) 147 cnt++; 148 else 149 cnt = 0; 150 } 151 } 152 } 153 154 private class C3Test 155 { 156 public C1Test sub_class; 157 public Thread sub_thread; 158 C3Test()159 public C3Test() 160 { 161 sub_class = new C1Test(); 162 sub_thread = new Thread(new ThreadStart(sub_class.TestMethod)); 163 } 164 TestMethod1()165 public void TestMethod1() 166 { 167 sub_thread.Start(); 168 Thread.Sleep (100); 169 #if MONO_FEATURE_THREAD_ABORT 170 sub_thread.Abort(); 171 #else 172 sub_thread.Interrupt (); 173 #endif 174 } 175 } 176 177 private class C4Test 178 { 179 public C1Test class1; 180 public C1Test class2; 181 public Thread thread1; 182 public Thread thread2; 183 public bool T1ON ; 184 public bool T2ON ; 185 C4Test()186 public C4Test() 187 { 188 T1ON = false; 189 T2ON = false; 190 class1 = new C1Test(); 191 class2 = new C1Test(); 192 thread1 = new Thread(new ThreadStart(class1.TestMethod)); 193 thread2 = new Thread(new ThreadStart(class2.TestMethod)); 194 } 195 TestMethod1()196 public void TestMethod1() 197 { 198 thread1.Start(); 199 TestUtil.WaitForAlive (thread1, "wait1"); 200 T1ON = true; 201 thread2.Start(); 202 TestUtil.WaitForAlive (thread2, "wait2"); 203 T2ON = true; 204 #if MONO_FEATURE_THREAD_ABORT 205 thread1.Abort(); 206 #else 207 thread1.Interrupt (); 208 #endif 209 TestUtil.WaitForNotAlive (thread1, "wait3"); 210 T1ON = false; 211 #if MONO_FEATURE_THREAD_ABORT 212 thread2.Abort(); 213 #else 214 thread2.Interrupt (); 215 #endif 216 TestUtil.WaitForNotAlive (thread2, "wait4"); 217 T2ON = false; 218 } 219 TestMethod2()220 public void TestMethod2() 221 { 222 thread1.Start(); 223 thread1.Join(); 224 } 225 } 226 227 [Test] TestCtor1()228 public void TestCtor1() 229 { 230 C1Test test1 = new C1Test(); 231 Thread t = new Thread (new ThreadStart (test1.TestMethod)); 232 233 Assert.IsTrue (t.CurrentCulture.IsReadOnly, "CurrentCulture.IsReadOnly"); 234 Assert.IsFalse (t.IsAlive, "IsAlive"); 235 Assert.IsFalse (t.IsBackground, "IsBackground"); 236 Assert.IsNull (t.Name, "Name"); 237 Assert.AreEqual (ThreadState.Unstarted, t.ThreadState, "ThreadState"); 238 } 239 240 [Test] 241 [Category ("NotWorking")] // we're not sharing (read-only) CultureInfo CultureInfo_Shared_Across_Threads()242 public void CultureInfo_Shared_Across_Threads () 243 { 244 Thread t = new Thread (TestCtor1); 245 Assert.AreSame (t.CurrentCulture, t.CurrentUICulture, "Culture"); 246 247 Assert.AreSame (t.CurrentCulture, CultureInfo.CurrentCulture, "CultureInfo.CurrentCulture"); 248 Assert.AreSame (t.CurrentUICulture, CultureInfo.CurrentUICulture, "CultureInfo.CurrentUICulture"); 249 250 Assert.AreSame (t.CurrentCulture, Thread.CurrentThread.CurrentCulture, "Thread.CurrentThread.CurrentCulture"); 251 Assert.AreSame (t.CurrentUICulture, Thread.CurrentThread.CurrentUICulture, "Thread.CurrentThread.CurrentUICulture"); 252 } 253 254 [Test] // bug #325566 GetHashCodeTest()255 public void GetHashCodeTest () 256 { 257 C1Test test1 = new C1Test (); 258 Thread tA = new Thread (new ThreadStart (test1.TestMethod)); 259 int hA1 = tA.GetHashCode (); 260 Assert.IsTrue (hA1 > 0, "#A1"); 261 tA.Start (); 262 int hA2 = tA.GetHashCode (); 263 Assert.AreEqual (hA1, hA2, "#A2"); 264 tA.Join (); 265 int hA3 = tA.GetHashCode (); 266 Assert.AreEqual (hA1, hA3, "#A3"); 267 Assert.AreEqual (hA1, tA.ManagedThreadId, "#A4"); 268 269 test1 = new C1Test (); 270 Thread tB = new Thread (new ThreadStart (test1.TestMethod)); 271 int hB1 = tB.GetHashCode (); 272 Assert.IsTrue (hB1 > 0, "#B1"); 273 tB.Start (); 274 int hB2 = tB.GetHashCode (); 275 Assert.AreEqual (hB1, hB2, "#B2"); 276 tB.Join (); 277 int hB3 = tB.GetHashCode (); 278 Assert.AreEqual (hB1, hB3, "#B3"); 279 Assert.AreEqual (hB1, tB.ManagedThreadId, "#B4"); 280 Assert.IsFalse (hA2 == hB2, "#B5"); 281 } 282 283 [Test] // bug #82700 ManagedThreadId()284 public void ManagedThreadId () 285 { 286 C1Test test1 = new C1Test (); 287 Thread t1 = new Thread (new ThreadStart (test1.TestMethod)); 288 int mtA1 = t1.ManagedThreadId; 289 t1.Start (); 290 int mtA2 = t1.ManagedThreadId; 291 t1.Join (); 292 int mtA3 = t1.ManagedThreadId; 293 Assert.AreEqual (mtA1, mtA2, "#A1"); 294 Assert.AreEqual (mtA2, mtA3, "#A2"); 295 296 test1 = new C1Test (); 297 Thread t2 = new Thread (new ThreadStart (test1.TestMethod)); 298 int mtB1 = t2.ManagedThreadId; 299 t2.Start (); 300 int mtB2 = t2.ManagedThreadId; 301 t2.Join (); 302 int mtB3 = t2.ManagedThreadId; 303 Assert.AreEqual (mtB1, mtB2, "#B1"); 304 Assert.AreEqual (mtB2, mtB3, "#B2"); 305 Assert.IsFalse (mtB1 == mtA1, "#B3"); 306 } 307 308 [Test] 309 [Category ("NotDotNet")] // it hangs. 310 [Category ("InterpreterNotWorking")] /* crashes on linux/arm64 */ TestStart()311 public void TestStart() 312 { 313 { 314 C1Test test1 = new C1Test(); 315 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 316 TestThread.Start(); 317 TestThread.Join(); 318 Assert.AreEqual (10, test1.cnt, "#1"); 319 } 320 { 321 C2Test test1 = new C2Test(); 322 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 323 TestThread.Start(); 324 #if MONO_FEATURE_THREAD_ABORT 325 TestThread.Abort(); 326 #else 327 TestThread.Interrupt (); 328 #endif 329 try { 330 TestThread.Start(); 331 Assert.Fail ("#2"); 332 } catch (ThreadStateException) { 333 } 334 } 335 { 336 C2Test test1 = new C2Test(); 337 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 338 TestThread.Start(); 339 while (!test1.run) { 340 } 341 bool started = (TestThread.ThreadState == ThreadState.Running); 342 Assert.AreEqual (started, test1.run, "#15 Thread Is not in the correct state: "); 343 #if MONO_FEATURE_THREAD_ABORT 344 TestThread.Abort(); 345 #else 346 TestThread.Interrupt (); 347 #endif 348 } 349 } 350 351 [Test] TestApartmentState()352 public void TestApartmentState () 353 { 354 C2Test test1 = new C2Test(); 355 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 356 Assert.AreEqual (ApartmentState.Unknown, TestThread.ApartmentState, "#1"); 357 TestThread.Start(); 358 TestUtil.WaitForAlive (TestThread, "wait5"); 359 Assert.AreEqual (ApartmentState.MTA, TestThread.ApartmentState, "#2"); 360 #if MONO_FEATURE_THREAD_ABORT 361 TestThread.Abort(); 362 #else 363 TestThread.Interrupt (); 364 #endif 365 } 366 367 [Test] 368 [Category ("NotWorking")] // setting the priority of a Thread before it is started isn't implemented in Mono yet TestPriority1()369 public void TestPriority1() 370 { 371 C2Test test1 = new C2Test(); 372 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 373 try { 374 TestThread.Priority=ThreadPriority.BelowNormal; 375 ThreadPriority before = TestThread.Priority; 376 Assert.AreEqual (ThreadPriority.BelowNormal, before, "#40 Unexpected priority before thread start: "); 377 TestThread.Start(); 378 TestUtil.WaitForAlive (TestThread, "wait7"); 379 ThreadPriority after = TestThread.Priority; 380 Assert.AreEqual (before, after, "#41 Unexpected Priority Change: "); 381 } finally { 382 #if MONO_FEATURE_THREAD_ABORT 383 TestThread.Abort(); 384 #else 385 TestThread.Interrupt (); 386 #endif 387 } 388 } 389 390 #if MONO_FEATURE_THREAD_ABORT 391 [Test] 392 [Category ("NotDotNet")] // on MS, Thread is still in AbortRequested state when Start is invoked AbortUnstarted()393 public void AbortUnstarted () 394 { 395 C2Test test1 = new C2Test(); 396 Thread th = new Thread (new ThreadStart (test1.TestMethod)); 397 th.Abort (); 398 th.Start (); 399 } 400 #endif 401 402 [Test] 403 [Category ("NotDotNet")] // on MS, ThreadState is immediately Stopped after Abort 404 [Category ("NotWorking")] // this is a MonoTODO -> no support for Priority TestPriority2()405 public void TestPriority2() 406 { 407 C2Test test1 = new C2Test(); 408 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 409 try { 410 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#42 Incorrect Priority in New thread: "); 411 TestThread.Start(); 412 TestUtil.WaitForAliveOrStop (TestThread, "wait8"); 413 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#43 Incorrect Priority in Started thread: "); 414 } finally { 415 #if MONO_FEATURE_THREAD_ABORT 416 TestThread.Abort(); 417 #else 418 TestThread.Interrupt (); 419 #endif 420 } 421 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#44 Incorrect Priority in Aborted thread: "); 422 } 423 424 [Test] 425 [Category ("NotWorking")] // this is a MonoTODO -> no support for Priority TestPriority3()426 public void TestPriority3() 427 { 428 C2Test test1 = new C2Test(); 429 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 430 try { 431 TestThread.Start(); 432 TestThread.Priority = ThreadPriority.Lowest; 433 Assert.AreEqual (ThreadPriority.Lowest, TestThread.Priority, "#45A Incorrect Priority:"); 434 TestThread.Priority = ThreadPriority.BelowNormal; 435 Assert.AreEqual (ThreadPriority.BelowNormal, TestThread.Priority, "#45B Incorrect Priority:"); 436 TestThread.Priority = ThreadPriority.Normal; 437 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#45C Incorrect Priority:"); 438 TestThread.Priority = ThreadPriority.AboveNormal; 439 Assert.AreEqual (ThreadPriority.AboveNormal, TestThread.Priority, "#45D Incorrect Priority:"); 440 TestThread.Priority = ThreadPriority.Highest; 441 Assert.AreEqual (ThreadPriority.Highest, TestThread.Priority, "#45E Incorrect Priority:"); 442 } 443 finally { 444 #if MONO_FEATURE_THREAD_ABORT 445 TestThread.Abort(); 446 #else 447 TestThread.Interrupt (); 448 #endif 449 } 450 } 451 452 [Test] 453 [Category ("InterpreterNotWorking")] TestUndivisibleByPageSizeMaxStackSize()454 public void TestUndivisibleByPageSizeMaxStackSize () 455 { 456 const int undivisible_stacksize = 1048573; 457 458 var thread = new Thread (new ThreadStart (delegate {}), undivisible_stacksize); 459 thread.Start (); 460 thread.Join (); 461 } 462 463 [Test] TestIsBackground1()464 public void TestIsBackground1 () 465 { 466 C2Test test1 = new C2Test(); 467 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 468 try { 469 TestThread.Start(); 470 TestUtil.WaitForAlive (TestThread, "wait9"); 471 bool state = TestThread.IsBackground; 472 Assert.IsFalse (state, "#51 IsBackground not set at the default state: "); 473 } finally { 474 #if MONO_FEATURE_THREAD_ABORT 475 TestThread.Abort(); 476 #else 477 TestThread.Interrupt (); 478 #endif 479 } 480 } 481 482 [Test] TestIsBackground2()483 public void TestIsBackground2 () 484 { 485 C2Test test1 = new C2Test(); 486 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 487 TestThread.IsBackground = true; 488 try { 489 TestThread.Start(); 490 } finally { 491 #if MONO_FEATURE_THREAD_ABORT 492 TestThread.Abort(); 493 #else 494 TestThread.Interrupt (); 495 #endif 496 } 497 498 if (TestThread.IsAlive) { 499 try { 500 Assert.IsTrue (TestThread.IsBackground, "#52 Is Background Changed to Start "); 501 } catch (ThreadStateException) { 502 // Ignore if thread died meantime 503 } 504 } 505 } 506 507 [Test] TestName()508 public void TestName() 509 { 510 C2Test test1 = new C2Test(); 511 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 512 try { 513 TestThread.Start(); 514 TestUtil.WaitForAlive (TestThread, "wait10"); 515 string name = TestThread.Name; 516 Assert.IsNull (name, "#61 Name set when mustn't be set: "); 517 string newname = "Testing...."; 518 TestThread.Name = newname; 519 Assert.AreEqual (newname, TestThread.Name, "#62 Name not set when must be set: "); 520 } finally { 521 #if MONO_FEATURE_THREAD_ABORT 522 TestThread.Abort(); 523 #else 524 TestThread.Interrupt (); 525 #endif 526 } 527 } 528 529 [Test] Name()530 public void Name () 531 { 532 Thread t = new Thread (new ThreadStart (Name)); 533 Assert.IsNull (t.Name, "Name-1"); 534 t.Name = null; 535 Assert.IsNull (t.Name, "Name-2"); 536 } 537 538 [Test] 539 [ExpectedException (typeof (InvalidOperationException))] Rename()540 public void Rename () 541 { 542 Thread t = new Thread (new ThreadStart (Rename)); 543 t.Name = "a"; 544 t.Name = "b"; 545 } 546 547 [Test] TestNestedThreads1()548 public void TestNestedThreads1() 549 { 550 C3Test test1 = new C3Test(); 551 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1)); 552 try { 553 TestThread.Start(); 554 TestUtil.WaitForAlive (TestThread, "wait11"); 555 } finally { 556 #if MONO_FEATURE_THREAD_ABORT 557 TestThread.Abort(); 558 #else 559 TestThread.Interrupt (); 560 #endif 561 } 562 } 563 564 [Test] TestNestedThreads2()565 public void TestNestedThreads2() 566 { 567 C4Test test1 = new C4Test(); 568 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1)); 569 try { 570 TestThread.Start(); 571 } finally { 572 #if MONO_FEATURE_THREAD_ABORT 573 TestThread.Abort(); 574 #else 575 TestThread.Interrupt (); 576 #endif 577 } 578 } 579 580 [Test] TestJoin1()581 public void TestJoin1() 582 { 583 C1Test test1 = new C1Test(); 584 C1Test test2 = new C1Test(); 585 Thread thread1 = new Thread(new ThreadStart(test1.TestMethod)); 586 Thread thread2 = new Thread(new ThreadStart(test1.TestMethod2)); 587 try { 588 thread1.Start(); 589 thread2.Start(); 590 thread2.Join(); 591 } finally { 592 #if MONO_FEATURE_THREAD_ABORT 593 thread1.Abort(); 594 thread2.Abort(); 595 #else 596 thread1.Interrupt (); 597 thread2.Interrupt (); 598 #endif 599 } 600 } 601 602 [Test] 603 [ExpectedException (typeof (ArgumentOutOfRangeException))] Join_Int32_Negative()604 public void Join_Int32_Negative () 605 { 606 // -1 is Timeout.Infinite 607 Thread.CurrentThread.Join (-2); 608 } 609 610 [Test] 611 [ExpectedException (typeof (ArgumentOutOfRangeException))] Join_TimeSpan_Negative()612 public void Join_TimeSpan_Negative () 613 { 614 Thread.CurrentThread.Join (Negative); 615 } 616 617 [Test] 618 [ExpectedException (typeof (ArgumentOutOfRangeException))] Join_TimeSpan_TooLarge()619 public void Join_TimeSpan_TooLarge () 620 { 621 Thread.CurrentThread.Join (TooLarge); 622 } 623 624 [Test] Join_TimeSpan_SmallNegative()625 public void Join_TimeSpan_SmallNegative () 626 { 627 Thread.CurrentThread.Join (SmallNegative); 628 } 629 630 [Test] 631 [ExpectedException (typeof (ArgumentOutOfRangeException))] Sleep_Int32_Negative()632 public void Sleep_Int32_Negative () 633 { 634 // -1 is Timeout.Infinite 635 Thread.Sleep (-2); 636 } 637 638 [Test] Sleep_TimeSpan_SmallNegative()639 public void Sleep_TimeSpan_SmallNegative () 640 { 641 Thread.Sleep (SmallNegative); 642 } 643 644 [Test] 645 [ExpectedException (typeof (ArgumentOutOfRangeException))] Sleep_TimeSpan_Negative()646 public void Sleep_TimeSpan_Negative () 647 { 648 Thread.Sleep (Negative); 649 } 650 651 [Test] 652 [ExpectedException (typeof (ArgumentOutOfRangeException))] Sleep_TimeSpan_TooLarge()653 public void Sleep_TimeSpan_TooLarge () 654 { 655 Thread.Sleep (TooLarge); 656 } 657 658 [Test] SpinWait()659 public void SpinWait () 660 { 661 // no exception for negative numbers 662 Thread.SpinWait (Int32.MinValue); 663 Thread.SpinWait (0); 664 } 665 666 [Test] TestThreadState()667 public void TestThreadState () 668 { 669 //TODO: Test The rest of the possible transitions 670 C2Test test1 = new C2Test(); 671 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod)); 672 Assert.AreEqual (ThreadState.Unstarted, TestThread.ThreadState, "#101 Wrong Thread State"); 673 try { 674 TestThread.Start(); 675 //while(!TestThread.IsAlive); //In the MS Documentation this is not necessary 676 //but in the MS SDK it is 677 Assert.IsTrue (TestThread.ThreadState == ThreadState.Running || (TestThread.ThreadState & ThreadState.Unstarted) != 0, 678 "#102 Wrong Thread State: " + TestThread.ThreadState.ToString ()); 679 } finally { 680 #if MONO_FEATURE_THREAD_ABORT 681 TestThread.Abort(); 682 #else 683 TestThread.Interrupt (); 684 #endif 685 } 686 687 TestUtil.WaitForNotAlive (TestThread, "wait12"); 688 // Docs say state will be Stopped, but Aborted happens sometimes (?) 689 Assert.IsTrue ((ThreadState.Stopped & TestThread.ThreadState) != 0 || (ThreadState.Aborted & TestThread.ThreadState) != 0, 690 "#103 Wrong Thread State: " + TestThread.ThreadState.ToString ()); 691 } 692 693 [Test] 694 [Ignore ("see comment below.")] CurrentPrincipal_PrincipalPolicy_NoPrincipal()695 public void CurrentPrincipal_PrincipalPolicy_NoPrincipal () 696 { 697 // note: switching from PrincipalPolicy won't work inside the same thread 698 // because as soon as a Principal object is created the Policy doesn't matter anymore 699 Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.NoPrincipal)); 700 try { 701 t.Start (); 702 t.Join (); 703 } catch { 704 #if MONO_FEATURE_THREAD_ABORT 705 t.Abort (); 706 #else 707 t.Interrupt (); 708 #endif 709 } 710 } 711 712 [Test] 713 [Ignore ("see comment below.")] CurrentPrincipal_PrincipalPolicy_UnauthenticatedPrincipal()714 public void CurrentPrincipal_PrincipalPolicy_UnauthenticatedPrincipal () 715 { 716 // note: switching from PrincipalPolicy won't work inside the same thread 717 // because as soon as a Principal object is created the Policy doesn't matter anymore 718 Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.UnauthenticatedPrincipal)); 719 try { 720 t.Start (); 721 t.Join (); 722 } catch { 723 #if MONO_FEATURE_THREAD_ABORT 724 t.Abort (); 725 #else 726 t.Interrupt (); 727 #endif 728 } 729 } 730 731 [Test] CurrentPrincipal_PrincipalPolicy_WindowsPrincipal()732 public void CurrentPrincipal_PrincipalPolicy_WindowsPrincipal () 733 { 734 // note: switching from PrincipalPolicy won't work inside the same thread 735 // because as soon as a Principal object is created the Policy doesn't matter anymore 736 Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.WindowsPrincipal)); 737 try { 738 t.Start (); 739 t.Join (); 740 } catch { 741 #if MONO_FEATURE_THREAD_ABORT 742 t.Abort (); 743 #else 744 t.Interrupt (); 745 #endif 746 } 747 } 748 749 [Test] IPrincipal_CopyOnNewThread()750 public void IPrincipal_CopyOnNewThread () 751 { 752 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("bad"), null); 753 Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.CopyOnNewThread)); 754 try { 755 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("good"), null); 756 t.Start (); 757 t.Join (); 758 } catch { 759 #if MONO_FEATURE_THREAD_ABORT 760 t.Abort (); 761 #else 762 t.Interrupt (); 763 #endif 764 } 765 } 766 767 int counter = 0; 768 769 #if MONO_FEATURE_THREAD_SUSPEND_RESUME 770 [Test] TestSuspend()771 public void TestSuspend () 772 { 773 Thread t = new Thread (new ThreadStart (DoCount)); 774 t.IsBackground = true; 775 t.Start (); 776 777 CheckIsRunning ("t1", t); 778 779 t.Suspend (); 780 WaitSuspended ("t2", t); 781 782 CheckIsNotRunning ("t3", t); 783 784 t.Resume (); 785 WaitResumed ("t4", t); 786 787 CheckIsRunning ("t5", t); 788 789 t.Abort (); 790 TestUtil.WaitForNotAlive (t, "wait13"); 791 CheckIsNotRunning ("t6", t); 792 } 793 #endif 794 795 #if MONO_FEATURE_THREAD_SUSPEND_RESUME && MONO_FEATURE_THREAD_ABORT 796 [Test] 797 [Category("NotDotNet")] // On MS, ThreadStateException is thrown on Abort: "Thread is suspended; attempting to abort" TestSuspendAbort()798 public void TestSuspendAbort () 799 { 800 Thread t = new Thread (new ThreadStart (DoCount)); 801 t.IsBackground = true; 802 t.Start (); 803 804 CheckIsRunning ("t1", t); 805 806 t.Suspend (); 807 WaitSuspended ("t2", t); 808 809 CheckIsNotRunning ("t3", t); 810 811 t.Abort (); 812 813 int n=0; 814 while (t.IsAlive && n < 200) { 815 Thread.Sleep (10); 816 n++; 817 } 818 819 Assert.IsTrue (n < 200, "Timeout while waiting for abort"); 820 821 CheckIsNotRunning ("t6", t); 822 } 823 #endif 824 825 [Test] Test_Interrupt()826 public void Test_Interrupt () 827 { 828 ManualResetEvent mre = new ManualResetEvent (false); 829 bool interruptedExceptionThrown = false; 830 831 ThreadPool.QueueUserWorkItem (Test_Interrupt_Worker, Thread.CurrentThread); 832 833 try { 834 try { 835 mre.WaitOne (3000); 836 } finally { 837 try { 838 mre.WaitOne (0); 839 } catch (ThreadInterruptedException) { 840 Assert.Fail ("ThreadInterruptedException thrown twice"); 841 } 842 } 843 } catch (ThreadInterruptedException) { 844 interruptedExceptionThrown = true; 845 } 846 847 Assert.IsTrue (interruptedExceptionThrown, "ThreadInterruptedException expected."); 848 } 849 850 [Test] 851 [ExpectedException (typeof (ArgumentNullException))] TestQueueUserWorkItemNullCallback()852 public void TestQueueUserWorkItemNullCallback () 853 { 854 ThreadPool.QueueUserWorkItem (null, null); 855 } 856 Test_Interrupt_Worker(object o)857 private void Test_Interrupt_Worker (object o) 858 { 859 Thread t = o as Thread; 860 Thread.Sleep (100); 861 t.Interrupt (); 862 } 863 864 [Test] Test_InterruptCurrentThread()865 public void Test_InterruptCurrentThread () 866 { 867 ManualResetEvent mre = new ManualResetEvent (false); 868 bool interruptedExceptionThrown = false; 869 870 Thread.CurrentThread.Interrupt (); 871 try { 872 mre.WaitOne (0); 873 Assert.Fail (); 874 } catch (ThreadInterruptedException) { 875 } 876 } 877 878 [Test] GetNamedDataSlotTest()879 public void GetNamedDataSlotTest () 880 { 881 Assert.IsNotNull (Thread.GetNamedDataSlot ("te#st"), "#1"); 882 Assert.AreSame (Thread.GetNamedDataSlot ("te#st"), Thread.GetNamedDataSlot ("te#st"), "#2"); 883 } 884 885 class DomainClass : MarshalByRefObject { 886 Thread m_thread; 887 bool success; 888 Run()889 public bool Run () { 890 m_thread = new Thread(ThreadProc); 891 m_thread.Start(Thread.CurrentThread); 892 m_thread.Join(); 893 return success; 894 } 895 ThreadProc(object arg)896 public void ThreadProc (object arg) { 897 success = m_thread == Thread.CurrentThread; 898 } 899 } 900 901 #if MONO_FEATURE_MULTIPLE_APPDOMAINS 902 [Test] 903 [Category ("NotDotNet")] CurrentThread_Domains()904 public void CurrentThread_Domains () 905 { 906 AppDomain ad = AppDomain.CreateDomain ("foo"); 907 ad.Load (typeof (DomainClass).Assembly.GetName ()); 908 var o = (DomainClass)ad.CreateInstanceAndUnwrap (typeof (DomainClass).Assembly.FullName, typeof (DomainClass).FullName); 909 Assert.IsTrue (o.Run ()); 910 AppDomain.Unload (ad); 911 } 912 #endif // MONO_FEATURE_MULTIPLE_APPDOMAINS 913 914 [Test] SetNameInThreadPoolThread()915 public void SetNameInThreadPoolThread () 916 { 917 Task t = Task.Run (delegate () { 918 Thread.CurrentThread.Name = "ThreadName1"; 919 Assert.AreEqual (Thread.CurrentThread.Name, "ThreadName1", "#1"); 920 921 try { 922 Thread.CurrentThread.Name = "ThreadName2"; 923 Assert.Fail ("#2"); 924 } catch (InvalidOperationException) { 925 } 926 }); 927 928 t.Wait (); 929 } 930 CheckIsRunning(string s, Thread t)931 void CheckIsRunning (string s, Thread t) 932 { 933 int c = counter; 934 Thread.Sleep (100); 935 Assert.IsTrue (counter > c, s); 936 } 937 CheckIsNotRunning(string s, Thread t)938 void CheckIsNotRunning (string s, Thread t) 939 { 940 int c = counter; 941 Thread.Sleep (100); 942 Assert.AreEqual (counter, c, s); 943 } 944 WaitSuspended(string s, Thread t)945 void WaitSuspended (string s, Thread t) 946 { 947 int n=0; 948 ThreadState state = t.ThreadState; 949 while ((state & ThreadState.Suspended) == 0) { 950 Assert.IsTrue ((state & ThreadState.SuspendRequested) != 0, s + ": expected SuspendRequested state"); 951 Thread.Sleep (10); 952 n++; 953 Assert.IsTrue (n < 100, s + ": failed to suspend"); 954 state = t.ThreadState; 955 } 956 Assert.IsTrue ((state & ThreadState.SuspendRequested) == 0, s + ": SuspendRequested state not expected"); 957 } 958 WaitResumed(string s, Thread t)959 void WaitResumed (string s, Thread t) 960 { 961 int n=0; 962 while ((t.ThreadState & ThreadState.Suspended) != 0) { 963 Thread.Sleep (10); 964 n++; 965 Assert.IsTrue (n < 100, s + ": failed to resume"); 966 } 967 } 968 DoCount()969 public void DoCount () 970 { 971 while (true) { 972 counter++; 973 Thread.Sleep (1); 974 } 975 } 976 } 977 978 [TestFixture] 979 public class ThreadStateTest { Start()980 void Start () 981 { 982 } 983 984 [Test] // bug #81720 IsBackGround()985 public void IsBackGround () 986 { 987 Thread t1 = new Thread (new ThreadStart (Start)); 988 Assert.AreEqual (ThreadState.Unstarted, t1.ThreadState, "#A1"); 989 Assert.IsFalse (t1.IsBackground, "#A2"); 990 t1.Start (); 991 t1.Join (); 992 Assert.AreEqual (ThreadState.Stopped, t1.ThreadState, "#A3"); 993 994 try { 995 bool isBackGround = t1.IsBackground; 996 Assert.Fail ("#A4: " + isBackGround.ToString ()); 997 } catch (ThreadStateException ex) { 998 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A5"); 999 Assert.IsNull (ex.InnerException, "#A6"); 1000 Assert.IsNotNull (ex.Message, "#A7"); 1001 } 1002 1003 Thread t2 = new Thread (new ThreadStart (Start)); 1004 Assert.AreEqual (ThreadState.Unstarted, t2.ThreadState, "#B1"); 1005 t2.IsBackground = true; 1006 Assert.AreEqual (ThreadState.Unstarted | ThreadState.Background, t2.ThreadState, "#B2"); 1007 Assert.IsTrue (t2.IsBackground, "#B3"); 1008 t2.Start (); 1009 t2.Join (); 1010 Assert.AreEqual (ThreadState.Stopped, t2.ThreadState, "#B4"); 1011 1012 try { 1013 bool isBackGround = t2.IsBackground; 1014 Assert.Fail ("#B5: " + isBackGround.ToString ()); 1015 } catch (ThreadStateException ex) { 1016 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B6"); 1017 Assert.IsNull (ex.InnerException, "#B7"); 1018 Assert.IsNotNull (ex.Message, "#B8"); 1019 } 1020 } 1021 1022 [Test] // bug #60031 StoppedThreadsThrowThreadStateException()1023 public void StoppedThreadsThrowThreadStateException () 1024 { 1025 var t = new Thread (() => { }); 1026 t.Start (); 1027 t.Join (); 1028 1029 Assert.Throws<ThreadStateException> (() => { var isb = t.IsBackground; }, "IsBackground getter"); 1030 Assert.Throws<ThreadStateException> (() => { var isb = t.ApartmentState; }, "ApartmentState getter"); 1031 Assert.Throws<ThreadStateException> (() => t.ApartmentState = ApartmentState.MTA, "ApartmentState setter"); 1032 Assert.Throws<ThreadStateException> (() => t.IsBackground = false, "IsBackground setter"); 1033 Assert.Throws<ThreadStateException> (() => t.Start (), "Start ()"); 1034 #if MONO_FEATURE_THREAD_SUSPEND_RESUME 1035 Assert.Throws<ThreadStateException> (() => t.Resume (), "Resume ()"); 1036 Assert.Throws<ThreadStateException> (() => t.Suspend (), "Suspend ()"); 1037 #endif 1038 Assert.Throws<ThreadStateException> (() => t.GetApartmentState (), "GetApartmentState ()"); 1039 Assert.Throws<ThreadStateException> (() => t.SetApartmentState (ApartmentState.MTA), "SetApartmentState ()"); 1040 Assert.Throws<ThreadStateException> (() => t.TrySetApartmentState (ApartmentState.MTA), "TrySetApartmentState ()"); 1041 } 1042 } 1043 1044 [TestFixture] 1045 [Serializable] 1046 public class ThreadTest_ManagedThreadId 1047 { 1048 AppDomain ad1; 1049 AppDomain ad2; 1050 MBRO mbro = new MBRO (); 1051 1052 class MBRO : MarshalByRefObject { 1053 public int id_a1; 1054 public int id_b1; 1055 public int id_b2; 1056 public string ad_a1; 1057 public string ad_b1; 1058 public string ad_b2; 1059 public string message; 1060 } 1061 #if !MOBILE 1062 [Test] ManagedThreadId_AppDomains()1063 public void ManagedThreadId_AppDomains () 1064 { 1065 AppDomain currentDomain = AppDomain.CurrentDomain; 1066 ad1 = AppDomain.CreateDomain ("AppDomain 1", currentDomain.Evidence, currentDomain.SetupInformation); 1067 ad2 = AppDomain.CreateDomain ("AppDomain 2", currentDomain.Evidence, currentDomain.SetupInformation); 1068 1069 Thread a = new Thread (ThreadA); 1070 Thread b = new Thread (ThreadB); 1071 // execute on AppDomain 1 thread A 1072 // execute on AppDomain 2 thread B 1073 // execute on AppDomain 1 thread B - must have same ManagedThreadId as Ad 2 on thread B 1074 a.Start (); 1075 a.Join (); 1076 b.Start (); 1077 b.Join (); 1078 1079 AppDomain.Unload (ad1); 1080 AppDomain.Unload (ad2); 1081 1082 if (mbro.message != null) 1083 Assert.Fail (mbro.message); 1084 1085 // Console.WriteLine ("Done id_a1: {0} id_b1: {1} id_b2: {2} ad_a1: {3} ad_b1: {4} ad_b2: {5}", mbro.id_a1, mbro.id_b1, mbro.id_b2, mbro.ad_a1, mbro.ad_b1, mbro.ad_b2); 1086 1087 Assert.AreEqual ("AppDomain 1", mbro.ad_a1, "Name #1"); 1088 Assert.AreEqual ("AppDomain 1", mbro.ad_b1, "Name #2"); 1089 Assert.AreEqual ("AppDomain 2", mbro.ad_b2, "Name #3"); 1090 1091 Assert.AreNotEqual (mbro.id_a1, mbro.id_b1, "Id #1"); 1092 Assert.AreNotEqual (mbro.id_a1, mbro.id_b2, "Id #2"); 1093 Assert.AreEqual (mbro.id_b1, mbro.id_b2, "Id #3"); 1094 1095 Assert.AreNotEqual (mbro.id_a1, Thread.CurrentThread.ManagedThreadId, "Id #4"); 1096 Assert.AreNotEqual (mbro.id_b1, Thread.CurrentThread.ManagedThreadId, "Id #5"); 1097 Assert.AreNotEqual (mbro.id_b2, Thread.CurrentThread.ManagedThreadId, "Id #6"); 1098 Assert.AreNotEqual (mbro.ad_a1, AppDomain.CurrentDomain.FriendlyName, "Name #4"); 1099 Assert.AreNotEqual (mbro.ad_b1, AppDomain.CurrentDomain.FriendlyName, "Name #5"); 1100 Assert.AreNotEqual (mbro.ad_b2, AppDomain.CurrentDomain.FriendlyName, "Name #6"); 1101 } 1102 #endif A1()1103 void A1 () 1104 { 1105 mbro.id_a1 = Thread.CurrentThread.ManagedThreadId; 1106 mbro.ad_a1 = AppDomain.CurrentDomain.FriendlyName; 1107 } 1108 B2()1109 void B2 () 1110 { 1111 mbro.id_b2 = Thread.CurrentThread.ManagedThreadId; 1112 mbro.ad_b2 = AppDomain.CurrentDomain.FriendlyName; 1113 } 1114 B1()1115 void B1 () 1116 { 1117 mbro.id_b1 = Thread.CurrentThread.ManagedThreadId; 1118 mbro.ad_b1 = AppDomain.CurrentDomain.FriendlyName; 1119 } 1120 ThreadA(object obj)1121 void ThreadA (object obj) 1122 { 1123 // Console.WriteLine ("ThreadA"); 1124 try { 1125 ad1.DoCallBack (A1); 1126 } catch (Exception ex) { 1127 mbro.message = string.Format ("ThreadA exception: {0}", ex); 1128 } 1129 // Console.WriteLine ("ThreadA Done"); 1130 } 1131 ThreadB(object obj)1132 void ThreadB (object obj) 1133 { 1134 // Console.WriteLine ("ThreadB"); 1135 try { 1136 ad2.DoCallBack (B2); 1137 ad1.DoCallBack (B1); 1138 } catch (Exception ex) { 1139 mbro.message = string.Format ("ThreadB exception: {0}", ex); 1140 } 1141 // Console.WriteLine ("ThreadB Done"); 1142 } 1143 } 1144 1145 [TestFixture] 1146 public class ThreadApartmentTest 1147 { Start()1148 void Start () 1149 { 1150 } 1151 1152 [Test] // bug #81658 ApartmentState_StoppedThread()1153 public void ApartmentState_StoppedThread () 1154 { 1155 Thread t1 = new Thread (new ThreadStart (Start)); 1156 t1.Start (); 1157 t1.Join (); 1158 try { 1159 ApartmentState state = t1.ApartmentState; 1160 Assert.Fail ("#A1: " + state.ToString ()); 1161 } catch (ThreadStateException ex) { 1162 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A2"); 1163 Assert.IsNull (ex.InnerException, "#A3"); 1164 Assert.IsNotNull (ex.Message, "#A4"); 1165 } 1166 1167 Thread t2 = new Thread (new ThreadStart (Start)); 1168 t2.IsBackground = true; 1169 t2.Start (); 1170 t2.Join (); 1171 try { 1172 ApartmentState state = t2.ApartmentState; 1173 Assert.Fail ("#B1: " + state.ToString ()); 1174 } catch (ThreadStateException ex) { 1175 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B2"); 1176 Assert.IsNull (ex.InnerException, "#B3"); 1177 Assert.IsNotNull (ex.Message, "#B4"); 1178 } 1179 } 1180 1181 [Test] ApartmentState_BackGround()1182 public void ApartmentState_BackGround () 1183 { 1184 Thread t1 = new Thread (new ThreadStart (Start)); 1185 t1.IsBackground = true; 1186 Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "#1"); 1187 t1.ApartmentState = ApartmentState.STA; 1188 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#2"); 1189 } 1190 1191 [Test] TestApartmentState()1192 public void TestApartmentState () 1193 { 1194 Thread t1 = new Thread (new ThreadStart (Start)); 1195 Thread t2 = new Thread (new ThreadStart (Start)); 1196 Thread t3 = new Thread (new ThreadStart (Start)); 1197 1198 Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "Thread1 Default"); 1199 Assert.AreEqual (ApartmentState.Unknown, t2.ApartmentState, "Thread2 Default"); 1200 Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Default"); 1201 1202 t1.ApartmentState = ApartmentState.STA; 1203 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once"); 1204 t1.ApartmentState = ApartmentState.MTA; 1205 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Twice"); 1206 1207 t2.ApartmentState = ApartmentState.MTA; 1208 Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Once"); 1209 t2.ApartmentState = ApartmentState.STA; 1210 Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Twice"); 1211 1212 bool exception_occured = false; 1213 try { 1214 t3.ApartmentState = ApartmentState.Unknown; 1215 } 1216 catch (Exception) { 1217 exception_occured = true; 1218 } 1219 Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Set Invalid"); 1220 Assert.IsFalse (exception_occured, "Thread3 Set Invalid Exception Occured"); 1221 1222 t1.Start (); 1223 exception_occured = false; 1224 try { 1225 t1.ApartmentState = ApartmentState.STA; 1226 } 1227 catch (Exception) { 1228 exception_occured = true; 1229 } 1230 Assert.IsTrue (exception_occured, "Thread1 Started Invalid Exception Occured"); 1231 } 1232 1233 [Test] TestSetApartmentStateSameState()1234 public void TestSetApartmentStateSameState () 1235 { 1236 Thread t1 = new Thread (new ThreadStart (Start)); 1237 t1.SetApartmentState (ApartmentState.STA); 1238 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once"); 1239 1240 t1.SetApartmentState (ApartmentState.STA); 1241 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set twice"); 1242 } 1243 1244 [Test] 1245 [ExpectedException(typeof(InvalidOperationException))] TestSetApartmentStateDiffState()1246 public void TestSetApartmentStateDiffState () 1247 { 1248 Thread t1 = new Thread (new ThreadStart (Start)); 1249 t1.SetApartmentState (ApartmentState.STA); 1250 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once"); 1251 1252 t1.SetApartmentState (ApartmentState.MTA); 1253 } 1254 1255 [Test] TestTrySetApartmentState()1256 public void TestTrySetApartmentState () 1257 { 1258 Thread t1 = new Thread (new ThreadStart (Start)); 1259 t1.SetApartmentState (ApartmentState.STA); 1260 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#1"); 1261 1262 bool result = t1.TrySetApartmentState (ApartmentState.MTA); 1263 Assert.IsFalse (result, "#2"); 1264 1265 result = t1.TrySetApartmentState (ApartmentState.STA); 1266 Assert.IsTrue (result, "#3"); 1267 } 1268 1269 [Test] TestTrySetApartmentStateRunning()1270 public void TestTrySetApartmentStateRunning () 1271 { 1272 Thread t1 = new Thread (new ThreadStart (Start)); 1273 t1.SetApartmentState (ApartmentState.STA); 1274 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#1"); 1275 1276 t1.Start (); 1277 1278 try { 1279 t1.TrySetApartmentState (ApartmentState.STA); 1280 Assert.Fail ("#2"); 1281 } catch (ThreadStateException) { 1282 } 1283 1284 t1.Join (); 1285 } 1286 1287 [Test] Volatile()1288 public void Volatile () { 1289 double v3 = 55667; 1290 Thread.VolatileWrite (ref v3, double.MaxValue); 1291 Assert.AreEqual (v3, double.MaxValue); 1292 1293 float v4 = 1; 1294 Thread.VolatileWrite (ref v4, float.MaxValue); 1295 Assert.AreEqual (v4, float.MaxValue); 1296 } 1297 1298 [Test] Culture()1299 public void Culture () 1300 { 1301 Assert.IsNotNull (Thread.CurrentThread.CurrentCulture, "CurrentCulture"); 1302 Assert.IsNotNull (Thread.CurrentThread.CurrentUICulture, "CurrentUICulture"); 1303 } 1304 1305 [Test] ThreadStartSimple()1306 public void ThreadStartSimple () 1307 { 1308 int i = 0; 1309 Thread t = new Thread (delegate () { 1310 // ensure the NSAutoreleasePool works 1311 i++; 1312 }); 1313 t.Start (); 1314 t.Join (); 1315 Assert.AreEqual (1, i, "ThreadStart"); 1316 } 1317 1318 [Test] ParametrizedThreadStart()1319 public void ParametrizedThreadStart () 1320 { 1321 int i = 0; 1322 object arg = null; 1323 Thread t = new Thread (delegate (object obj) { 1324 // ensure the NSAutoreleasePool works 1325 i++; 1326 arg = obj; 1327 }); 1328 t.Start (this); 1329 t.Join (); 1330 1331 Assert.AreEqual (1, i, "ParametrizedThreadStart"); 1332 Assert.AreEqual (this, arg, "obj"); 1333 } 1334 1335 [Test] SetNameTpThread()1336 public void SetNameTpThread () { 1337 ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); 1338 } 1339 ThreadProc(Object stateInfo)1340 static void ThreadProc(Object stateInfo) { 1341 Thread.CurrentThread.Name = "My Worker"; 1342 } 1343 1344 [Test] GetStackTraces()1345 public void GetStackTraces () { 1346 var m = typeof (Thread).GetMethod ("Mono_GetStackTraces", BindingFlags.NonPublic|BindingFlags.Static); 1347 if (m != null) { 1348 var res = (Dictionary<Thread,SD.StackTrace>)typeof (Thread).GetMethod ("Mono_GetStackTraces", BindingFlags.NonPublic|BindingFlags.Static).Invoke (null, null); 1349 foreach (var t in res.Keys) { 1350 var st = res [t].ToString (); 1351 } 1352 } 1353 } 1354 } 1355 1356 public class TestUtil 1357 { WaitForNotAlive(Thread t, string s)1358 public static void WaitForNotAlive (Thread t, string s) 1359 { 1360 WhileAlive (t, true, s); 1361 } 1362 WaitForAlive(Thread t, string s)1363 public static void WaitForAlive (Thread t, string s) 1364 { 1365 WhileAlive (t, false, s); 1366 } 1367 WaitForAliveOrStop(Thread t, string s)1368 public static bool WaitForAliveOrStop (Thread t, string s) 1369 { 1370 return WhileAliveOrStop (t, false, s); 1371 } 1372 WhileAlive(Thread t, bool alive, string s)1373 public static void WhileAlive (Thread t, bool alive, string s) 1374 { 1375 var sw = SD.Stopwatch.StartNew (); 1376 while (t.IsAlive == alive) { 1377 if (sw.Elapsed.TotalSeconds > 10) { 1378 if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s); 1379 else Assert.Fail ("Timeout while waiting for alive state. " + s); 1380 } 1381 } 1382 } 1383 WhileAliveOrStop(Thread t, bool alive, string s)1384 public static bool WhileAliveOrStop (Thread t, bool alive, string s) 1385 { 1386 var sw = SD.Stopwatch.StartNew (); 1387 while (t.IsAlive == alive) { 1388 if (t.ThreadState == ThreadState.Stopped) 1389 return false; 1390 1391 if (sw.Elapsed.TotalSeconds > 10) { 1392 if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s); 1393 else Assert.Fail ("Timeout while waiting for alive state. " + s); 1394 } 1395 } 1396 1397 return true; 1398 } 1399 } 1400 } 1401