Thread.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.Generic; 6 using System.Diagnostics; 7 using System.Globalization; 8 using System.Threading; 9 10 // <summary> 11 // Logging. 12 // </summary> 13 // <history> 14 // 2008 created by Truong Do (ductdo). 15 // 2009-... modified by Truong Do (TruongDo). 16 // 2023- Included in PowerToys. 17 // </history> 18 namespace MouseWithoutBorders.Core; 19 20 internal sealed class Thread 21 { 22 private static readonly Lock ThreadsLock = new(); 23 private static List<System.Threading.Thread> threads; 24 25 private readonly System.Threading.Thread thread; 26 27 internal Thread(ThreadStart callback, string name) 28 { 29 UpdateThreads(thread = new System.Threading.Thread(callback) { Name = name }); 30 } 31 32 internal Thread(ParameterizedThreadStart callback, string name) 33 { 34 UpdateThreads(thread = new System.Threading.Thread(callback) { Name = name }); 35 } 36 37 internal static void UpdateThreads(System.Threading.Thread thread) 38 { 39 lock (ThreadsLock) 40 { 41 bool found = false; 42 List<System.Threading.Thread> toBeRemovedThreads = new(); 43 threads ??= new List<System.Threading.Thread>(); 44 45 foreach (System.Threading.Thread t in threads) 46 { 47 if (!t.IsAlive) 48 { 49 toBeRemovedThreads.Add(t); 50 } 51 else if (t.ManagedThreadId == thread.ManagedThreadId) 52 { 53 found = true; 54 } 55 } 56 57 foreach (System.Threading.Thread t in toBeRemovedThreads) 58 { 59 _ = threads.Remove(t); 60 } 61 62 if (!found) 63 { 64 threads.Add(thread); 65 } 66 } 67 } 68 69 internal static string DumpThreadsStack() 70 { 71 string stack = "\r\nMANAGED THREADS: " + threads.Count.ToString(CultureInfo.InvariantCulture) + "\r\n"; 72 stack += Logger.GetStackTrace(new StackTrace()); 73 return stack; 74 } 75 76 internal void SetApartmentState(ApartmentState apartmentState) 77 { 78 thread.SetApartmentState(apartmentState); 79 } 80 81 internal void Start() 82 { 83 thread.Start(); 84 } 85 86 internal void Start(object parameter) 87 { 88 thread.Start(parameter); 89 } 90 91 internal static void Sleep(int millisecondsTimeout) 92 { 93 System.Threading.Thread.Sleep(millisecondsTimeout); 94 } 95 96 internal static System.Threading.Thread CurrentThread => System.Threading.Thread.CurrentThread; 97 98 internal ThreadPriority Priority 99 { 100 get => thread.Priority; 101 set => thread.Priority = value; 102 } 103 104 internal System.Threading.ThreadState ThreadState => thread.ThreadState; 105 }