0

我有一个class WorkerTaskEvent : IDisposable具有 type 属性的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 究竟会做什么,所以如果在这个方法被杀死时丢失了任何资源,那很好。然而,远非完美。但是清理将是那些创建这个委托背后的方法的人的责任。

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

4

1 回答 1

1

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

当您将取消令牌传递给Task.Factory.StartNew()它时,即使在实际计划任务之前取消令牌源的情况。但是,一旦任务开始运行,正在运行的委托有责任检查并停止取消的令牌。

因此,您应该定义您的委托ExecuteTaskMethod,使其接受 CancellationToken 参数。然后你把它留给委托实现者来取消令牌。

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

另请参阅此处的答案:如何中止/取消 TPL 任务?

于 2013-07-18T19:26:32.823 回答