Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public static class AbortableThreadContext
- {
- [DllImport("kernel32.dll")]
- private static extern uint GetCurrentThreadId();
- [DllImport("kernel32.dll")]
- private static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
- [DllImport("kernel32.dll")]
- private static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
- public static Task ExecuteAsync(Action action, CancellationToken ct)
- {
- var taskCompletionSource = new TaskCompletionSource();
- var resetEvent = new AutoResetEvent(false);
- uint threadId = 0;
- var thread = new Thread(() =>
- {
- Thread.BeginThreadAffinity();
- threadId = GetCurrentThreadId();
- Thread.EndThreadAffinity();
- resetEvent.Set();
- action();
- taskCompletionSource.TrySetResult();
- })
- {
- IsBackground = true
- };
- thread.Start();
- resetEvent.WaitOne();
- ct.UnsafeRegister(_ =>
- {
- if (thread.IsAlive)
- {
- var ptrThread = OpenThread(1, false, threadId);
- TerminateThread(ptrThread, 1);
- taskCompletionSource.TrySetCanceled(ct);
- }
- thread = null;
- }, null);
- return taskCompletionSource.Task;
- }
- public static Task<T> ExecuteAsync<T>(Func<T> action, CancellationToken ct)
- {
- var taskCompletionSource = new TaskCompletionSource<T>();
- var resetEvent = new AutoResetEvent(false);
- uint threadId = 0;
- var thread = new Thread(() =>
- {
- Thread.BeginThreadAffinity();
- threadId = GetCurrentThreadId();
- Thread.EndThreadAffinity();
- resetEvent.Set();
- var result = action();
- taskCompletionSource.TrySetResult(result);
- })
- {
- IsBackground = true
- };
- thread.Start();
- resetEvent.WaitOne();
- ct.UnsafeRegister(_ =>
- {
- if (thread.IsAlive)
- {
- var ptrThread = OpenThread(1, false, threadId);
- TerminateThread(ptrThread, 1);
- taskCompletionSource.TrySetCanceled(ct);
- }
- thread = null;
- }, null);
- return taskCompletionSource.Task;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement