超时时取消任务内的任务.c#
本文关键字:任务 超时 取消 | 更新日期: 2023-09-27 18:11:56
我正在尝试运行任务集合。我有一个procesing object model
,我不知道它的性质。这就是为什么我创建了这个类的子类。我有一个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()
。我正在尝试使用timer
和CancellationToken
。但是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()
。
假设这是一个示例。我假设你的大脑正在做一些持续的工作,而不仅仅是睡觉。否则,你可以使用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);
}