使用正在运行的任务处置对象?

时间:2013-07-18 15:22:01

标签: multithreading c#-4.0

我有class WorkerTaskEvent : IDisposable,其属性类型为Task。在创建时,它将创建一个新任务,它将在后台运行某些方法,该方法应该在某个时刻结束 但是,有时候任务并没有结束,因此永远将记忆保存在记忆中。现在我使用取消令牌发送取消消息,我这样做:

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));
    }
}

(还有更多代码,包括检查任务是否在特定时间内结束的代码。)
我不能让这个任务永远运行,我希望这是一个合适的解决方案,但也许其他人有更好的选择?
我完全无法控制TaskMethod会做什么,所以如果在杀死这个方法时丢失了任何资源,那很好。但是,远非完美。但是,清理将是创建此委托背后方法的人的责任。

虽然将取消令牌传递给委托方法可能会有很大帮助,但我不能将其用作解决方案,因为委托方法是第三方库的一部分,并且它不应该以无限循环结束。墨菲定律再次在我脸上笑了起来,因为代表确实倾向于无休止地循环。也许我可以在这个库的下一个版本中传递一个取消令牌(我已经要求了)但是现在我必须以一种艰难的方式停止无限循环......

1 个答案:

答案 0 :(得分:1)

任务取消是合作的,不应强迫。

当您将取消令牌传递给Task.Factory.StartNew()时,即使在实际安排任务之前取消令牌源也是如此。但是,一旦任务开始运行,正在运行的委托负责检查并停止取消的令牌。

因此,您应该定义委托ExecuteTaskMethod,使其接受CancellationToken参数。然后,您将其留给委托实施者取消令牌。

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

另见答案:How do I abort/cancel TPL Tasks?