重新启动已完成的任务

10

我有一个定时在应用程序后台运行的任务。第一次运行它时一切正常,任务顺利结束。但是第二次及之后每当我使用task.Start()时都会抛出异常:

'mscorlib.dll' 中发生了未经处理的类型为 'System.InvalidOperationException' 的异常 其他信息: 无法在已完成的任务上调用 Start。

我确定我的任务函数运行到了末尾..我该怎么做才能定期运行任务?


3
你需要重复使用同一个“Task”吗?你是否可以每次运行代码时都创建一个新的“Task”? - Michael
2个回答

16

Stephen Taub解释了这个问题(我实际上可以推荐阅读他关于Tasks的更多文章)

  1. 问题:我可以在同一个Task上调用多次Start方法吗?

不可以。任务只能从已创建状态转换一次,而Start方法将任务从已创建状态转换出去:因此,Start方法只能使用一次。任何尝试在不处于已创建状态的任务上调用Start方法都会导致异常。 Start方法采用同步机制确保任务对象即使同时被多次调用仍然保持一致状态...只有其中一个呼叫可能成功。

.. 这也是您看到的。您可以例如使用计时器并每次启动新任务。
如果需要检查一次只运行一个任务,可以在当前正在运行的任务上检查TaskStatus.RanToCompletion


3

请看一下System.Threading.Timer,它可以让您定期执行回调方法。对于需要每小时、重复等运行的任务非常有用。如果需要确保计时器仅同步运行(以防运行重叠),请不要忘记锁定回调方法体。


感谢您友好的回复! - default
实际上,Threading.Timer 也是线程安全的(在这里底部有说明)。我的错误。 - default
我一直被告知要使用Threading.Timer而不是其他版本,因为它是更高效的版本。老实说,我没有深入研究过这个问题。 - Haney
那我们俩一样啊。我有一段时间前偶然看到了那个SO帖子,从那以后就一直把它当作指南使用。只是现在我看到了一个反驳得票最高答案的评论。 - default
3
另外一件事,老实说,就是 永远不要 相信 MSDN 上的线程安全信息。它的错误率远高于正确率。 - Haney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接