0

I have a class WorkerTaskEvent : IDisposable which has a property of type Task. On creation, it will create a new task, which will run some method in the background which is supposed to end at some point.
However, sometimes the task does not end, thus keeping things in memory forever. Right now I use a cancellation token to send a cancel message and I do this like this:

public WorkerTaskEvent(ExecuteTaskMethod taskMethod)
{
    TaskMethod = taskMethod;
    RunningTask = Task.Factory.StartNew(OnExecuteTask, Token.Token); 
}

private void OnExecuteTask()
{
    if (TaskMethod != null) TaskMethod();
}

public void Dispose()
{
    if (RunningTask != null && !RunningTask.IsCompleted)
    {
        Token.CancelAfter(TimeSpan.FromMinutes(1));
    }
}

(There's more code, including code to check if the task ends within a specific amount of time.)
I can't have this task running forever and I'm hoping this is a proper solution, but perhaps someone else has a better option?
I have absolutely no control over what TaskMethod will do exactly, so if any resources are lost when this method is killed, fine. Far from perfect, though. But clean-up will be the responsibility of those who create the method behind this delegate.

While passing a cancellation token to the delegated method might help a lot, I can't use this as a solution since the delegated method is part of a third-party library and it's not supposed to end in an endless loop. Murphy's law is laughing me in my face again, since the delegate does tend to loop endlessly, though. Maybe I can pass a cancellation token in the next version of this library (I've requested this) but for now I have to stop the endless loop in a hard way...

Wim ten Brink
  • 25,901
  • 20
  • 83
  • 149
  • No. I need to know if I can end a thread in some way if it ends up in an endless loop. But i found an alternative solution so the Q can stay closed. – Wim ten Brink Jul 19 '13 at 19:44

1 Answers1

1

Task cancellation is co-operative and should not be forced.

When you pass cancellation token to Task.Factory.StartNew() it is for the case when the token source is cancelled even before the task was actually scheduled. However, once the task has started running, it is the responsibility of the running delegate to check and stop on the cancelled token.

Hence you should define your delegate ExecuteTaskMethod such that it accepts a CancellationToken parameter. Then you leave it up to the delegate implementer to cancel on the token.

private void OnExecuteTask()
{
    if (TaskMethod != null) TaskMethod(Token.Token);
}

Also see the answer here: How do I abort/cancel TPL Tasks?

Community
  • 1
  • 1
YK1
  • 7,327
  • 1
  • 21
  • 28
  • Unfortunately, the cancellation token cannot be passed to the delegated method, since it's code is outside my control and part of a custom library. This custom library is supposed to have no endless loops, but occasionally it does end up in an endless loop with no way to end it. (And no way to alter the code.) – Wim ten Brink Jul 19 '13 at 07:51
  • One alternative would be to instantiate `WorkerTaskEvent` in new AppDomain and then bring down the AppDomain when you want to force kill that task - this assuming that you said `so if any resources are lost when this method is killed, fine`. – YK1 Jul 20 '13 at 12:41