Advertisement
Guest User

Untitled

a guest
Apr 16th, 2022
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.70 KB | None | 0 0
  1.  public static class AbortableThreadContext
  2.     {
  3.         [DllImport("kernel32.dll")]
  4.         private static extern uint GetCurrentThreadId();
  5.  
  6.         [DllImport("kernel32.dll")]
  7.         private static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
  8.  
  9.         [DllImport("kernel32.dll")]
  10.         private static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
  11.  
  12.  
  13.         public static Task ExecuteAsync(Action action, CancellationToken ct)
  14.         {
  15.             var taskCompletionSource = new TaskCompletionSource();
  16.             var resetEvent = new AutoResetEvent(false);
  17.             uint threadId = 0;
  18.  
  19.             var thread = new Thread(() =>
  20.             {
  21.                 Thread.BeginThreadAffinity();
  22.                 threadId = GetCurrentThreadId();
  23.                 Thread.EndThreadAffinity();
  24.  
  25.                 resetEvent.Set();
  26.                 action();
  27.                 taskCompletionSource.TrySetResult();
  28.             })
  29.             {
  30.                 IsBackground = true
  31.             };
  32.  
  33.             thread.Start();
  34.  
  35.             resetEvent.WaitOne();
  36.  
  37.             ct.UnsafeRegister(_ =>
  38.             {
  39.                 if (thread.IsAlive)
  40.                 {
  41.                     var ptrThread = OpenThread(1, false, threadId);
  42.                     TerminateThread(ptrThread, 1);
  43.                     taskCompletionSource.TrySetCanceled(ct);
  44.                 }
  45.                 thread = null;
  46.             }, null);
  47.            
  48.  
  49.             return taskCompletionSource.Task;
  50.         }
  51.  
  52.         public static Task<T> ExecuteAsync<T>(Func<T> action, CancellationToken ct)
  53.         {
  54.             var taskCompletionSource = new TaskCompletionSource<T>();
  55.             var resetEvent = new AutoResetEvent(false);
  56.             uint threadId = 0;
  57.  
  58.             var thread = new Thread(() =>
  59.             {
  60.                 Thread.BeginThreadAffinity();
  61.                 threadId = GetCurrentThreadId();
  62.                 Thread.EndThreadAffinity();
  63.  
  64.                 resetEvent.Set();
  65.                 var result = action();
  66.                 taskCompletionSource.TrySetResult(result);
  67.             })
  68.             {
  69.                 IsBackground = true
  70.             };
  71.  
  72.             thread.Start();
  73.  
  74.             resetEvent.WaitOne();
  75.  
  76.             ct.UnsafeRegister(_ =>
  77.             {
  78.                 if (thread.IsAlive)
  79.                 {
  80.                     var ptrThread = OpenThread(1, false, threadId);
  81.                     TerminateThread(ptrThread, 1);
  82.                     taskCompletionSource.TrySetCanceled(ct);
  83.                 }
  84.                 thread = null;
  85.             }, null);
  86.  
  87.  
  88.             return taskCompletionSource.Task;
  89.         }
  90.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement