Reputation: 691
I'm trying to run collection of tasks. I have a procesing object model
, which properties I don't know. That's is why I've created a child of this class. I have a collection of ProcesingTask
objects. This is my code:
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);
}
}
I need to stop DoTaskWork()
if running time was timed out. I'm trying to use timer
and CancellationToken
. But DoTaskWork()
still doing his job after TimedOut()
. Is any way to resolve this issue?
Upvotes: 0
Views: 81
Reputation: 7028
You have to implement your method DoTaskWork()
accordingly.
Assume this as a sample. I am assuming that your thead is doing some continuos work rather just sleep. Otherwise you can use abort method which will just abort the thread even if its in sleep mode.
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);
}
Upvotes: 1
Reputation: 18013
Though you send the cancel signal, you don't do anything with that in 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);
}
Upvotes: 1