超时时取消任务内的任务。 C#

Cancel Task inside task when timed out. C#

我正在尝试 运行 收集任务。我有一个 procesing object model,我不知道哪些属性。这就是为什么我创建了这个 class 的子项的原因。我有一个 ProcesingTask 个对象的集合。这是我的代码:

 public sealed class ProcessingTask : ProcessingObject
    {
        private CancellationTokenSource cancelToken;
        private System.Timers.Timer _timer;
        public int TimeOut {private get; set; }
        public int ProcessObjectID { get; private set; }         
        public Task ProcessObjectTask { get; private set; }
        public QueueObject queueObject { private get; set; }
        public ProcessingTask(int processObjectID)
        {          
            this.ProcessObjectID = processObjectID;
            ResetTask();               
        }
    private void InitialTimeOut()
    {
        _timer = new System.Timers.Timer(TimeOut);
        _timer.Elapsed += new ElapsedEventHandler(TimedOut);
        _timer.Enabled = true;
    }
    private void TimedOut(object sender, ElapsedEventArgs e)
    {
         cancelToken.Cancel();
         Console.WriteLine("Thread {0} was timed out...", ProcessObjectID);
        _timer.Stop();            
    }
    public void ResetTask()
    {
        cancelToken = new CancellationTokenSource();
        ProcessObjectTask = new Task(() => DoTaskWork(), cancelToken.Token);            
    }
    public void DoTaskWork()
    {
        InitialTimeOut();     
        Random rand = new Random();
        int operationTime = rand.Next(2000, 20000);               
        Thread.Sleep(operationTime);
        _timer.Stop();          
         Console.WriteLine("Thread {0} was finished...", ProcessObjectID);            
    }       
}

public class CustomThreadPool
    {
        private IList<ProcessingTask> _processingTasks;      
        public CustomThreadPool(List<ProcessingTask> processingObjects)
        {           
            this._processingTasks = processingObjects;
        }
        public void RunThreadPool(Queue<QueueObject> queue, int batchSize)
        {
            for (int i = 1; i <= batchSize; i++)
            {
                QueueObject queueObject = queue.ToArray().ToList().FirstOrDefault();

                ProcessingTask task = _processingTasks.FirstOrDefault(x => x.ProcessObjectID == queueObject.QueueObjectId);                
                task.queueObject = queue.Dequeue();
                task.TimeOut = 3000;
                task.ProcessObjectTask.Start();   
            }
        }

        public void WaitAll()
        {
            var tasks = _processingTasks.Select(x => x.ProcessObjectTask).ToArray();           
            Task.WaitAll(tasks); 
        }
    }

如果运行宁时间超时,我需要停止DoTaskWork()。我正在尝试使用 timerCancellationToken。但是 DoTaskWork()TimedOut() 之后仍在做他的工作。有什么办法可以解决这个问题吗?

尽管您发送了取消信号,但在 DoTaskWork

中您没有对此做任何事情
public void DoTaskWork()
{
    InitialTimeOut();     
    Random rand = new Random();
    int operationTime = rand.Next(2000, 20000);

    // Thread.Sleep(operationTime); // this imitates a non-responsive operation

    // but this imitates a responsive operation:
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    while (!cancelToken.IsCancellationRequested
      && stopwatch.ElapsedMilliseconds < operationTime)
    {
        Thread.Sleep(10);
    }

    _timer.Stop();          
     Console.WriteLine("Thread {0} was finished...", ProcessObjectID);            
}       

您必须相应地实施您的方法DoTaskWork()

以此为样本。我假设你的 thead 正在做一些连续的工作而不是只是睡觉。否则你可以使用 abort 方法,即使它处于睡眠模式也会中止线程。

public void DoTaskWork()
    {
        InitialTimeOut();
        Random rand = new Random();
        int operationTime = rand.Next(2000, 20000);
        while (true)
        {
            if (cancelToken.IsCancellationRequested)
            {
                throw new Exception("Cancellation requested.");
            }
            Thread.Sleep(operationTime);
        }
        _timer.Stop();
        Console.WriteLine("Thread {0} was finished...", ProcessObjectID);
    }