Using a CancellationToken to cancel a task without explicitly checking within the task?

前端 未结 3 1058
遇见更好的自我
遇见更好的自我 2020-12-21 07:31

Background:

I have a web application which kicks off long running (and stateless) tasks:

var          


        
3条回答
  •  生来不讨喜
    2020-12-21 08:01

    If you are OK with the implications of Thread.Abort (disposables not disposed, locks not released, application state corrupted), then here is how you could implement non-cooperative cancellation by aborting the task's dedicated thread.

    private static Task RunAbortable(Func function,
        CancellationToken cancellationToken)
    {
        var tcs = new TaskCompletionSource();
        var thread = new Thread(() =>
        {
            try
            {
                TResult result;
                using (cancellationToken.Register(Thread.CurrentThread.Abort))
                {
                    result = function();
                }
                tcs.SetResult(result);
            }
            catch (ThreadAbortException)
            {
                tcs.TrySetCanceled();
            }
            catch (Exception ex)
            {
                tcs.TrySetException(ex);
            }
        });
        thread.IsBackground = true;
        thread.Start();
        return tcs.Task;
    }
    

    Usage example:

    var cts = new CancellationTokenSource();
    var task = RunAbortable(() => DoWork(foo), cts.Token);
    task.Wait();
    

提交回复
热议问题