使用TPL取消任务

时间:2013-12-04 12:17:28

标签: c# .net-4.0 task-parallel-library

我有一个带2个按钮的用户界面 - “开始”和“停止”。当我按下“开始”按钮时,我需要生成一个在后台执行某项操作的任务。当我点击“停止”时,如果有任何任务正在主动运行任务,那么我需要取消它们。现在如果我再次单击Start而不停止,则应该停止任何活动任务并生成一个新任务。此外,还应记录任何取消。

我有一个小类,它使用TPL(我是初学者)执行任务的启动和停止,但我不确定这是否是正确的方法来执行此操作,就所使用的构造而言。问题是 - 是否有更好的方法(较少的代码,框架api)使用TPL实现这一点。请注意,我使用的是.NET 4.0,而async对我来说无法使用。

代码:

public class Runner
    {
        private readonly List<CancellationTokenSource> _activeTokenSource = new List<CancellationTokenSource>();
        private readonly List<Task> _activeTasks = new List<Task>();

        public void Start()
        {
            StopAnyActiveTasks();
            var activeTokenSource = new CancellationTokenSource();
            var activeCancellationToken = activeTokenSource.Token;
            var task = new Task<ValueObject>(x =>
            {
                activeCancellationToken.ThrowIfCancellationRequested();                
                Thread.Sleep(TimeSpan.FromSeconds(10));
                activeCancellationToken.ThrowIfCancellationRequested();
                return new ValueObject();
            }, activeCancellationToken);
            task.ContinueWith(ant =>
            {
                try
                {
                    var result = ant.Result;
                }
                catch (AggregateException e)
                {
                    e.InnerExceptions.ToList()
                        .ForEach(x => System.Diagnostics.Debug.WriteLine("Exception" + x.Message));
                }
            }, TaskContinuationOptions.OnlyOnRanToCompletion);
            task.ContinueWith(ant =>
            {
                try
                {
                    var result = ant.Result;
                }
                catch (AggregateException e)
                {
                    e.InnerExceptions.ToList()
                        .ForEach(x => System.Diagnostics.Debug.WriteLine("Aggregate Exception on cancellation" + x.Message));
                }
            }, TaskContinuationOptions.OnlyOnFaulted);

            _activeTasks.Add(task);
            _activeTokenSource.Add(activeTokenSource);
            task.Start();
        }

        public void StopAnyActiveTasks()
        {
            if (_activeTasks.Count <= 0)
                return;

            foreach (var cancellationTokenSource in _activeTokenSource)
            {
                if (!cancellationTokenSource.IsCancellationRequested)
                    cancellationTokenSource.Cancel();
            }

        }
    }

0 个答案:

没有答案