C# 如果超时时间过去而任务未完成,Task.Wait(int)是否停止任务?
我有一个任务,我希望它需要不到一秒钟的时间运行,但如果它需要超过几秒钟,我想取消该任务 例如:C# 如果超时时间过去而任务未完成,Task.Wait(int)是否停止任务?,c#,.net,multithreading,task-parallel-library,task,C#,.net,Multithreading,Task Parallel Library,Task,我有一个任务,我希望它需要不到一秒钟的时间运行,但如果它需要超过几秒钟,我想取消该任务 例如: Task t = new Task(() => { while (true) { Thread.Sleep(500); } }); t.Start(); t.Wait(3000); 请注意,3000毫秒后等待将过期。超时过期时任务是否已取消,或者任务是否仍在运
Task t = new Task(() =>
{
while (true)
{
Thread.Sleep(500);
}
});
t.Start();
t.Wait(3000);
请注意,3000毫秒后等待将过期。超时过期时任务是否已取消,或者任务是否仍在运行?任务仍在运行,直到您明确告诉它停止或循环完成(这永远不会发生) 您可以检查Wait的返回值以查看以下内容: (来自) 返回值 类型:System.Boolean 如果任务在分配的时间内完成执行,则为true;否则,错误 超时过期时任务是否已取消,或者任务是否仍在运行 不,是的 传递给
Task.Wait
的超时是针对Wait
,而不是针对任务。Task.Wait()
等待到指定的任务完成时间,并返回任务是否在指定的时间量(或更早)内完成。任务本身不被修改,也不依赖于等待
阅读里德·科佩的《尼斯系列》
及:
检查以下代码:
var cts = new CancellationTokenSource();
var newTask = Task.Factory.StartNew(state =>
{
var token = (CancellationToken)state;
while (!token.IsCancellationRequested)
{
}
token.ThrowIfCancellationRequested();
}, cts.Token, cts.Token);
if (!newTask.Wait(3000, cts.Token)) cts.Cancel();
如果要取消
任务
,则应在创建任务时传入取消令牌
。这将允许您从外部取消任务。如果你愿意的话,你可以把取消和计时器联系起来
要使用取消令牌创建任务,请参见以下示例:
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var t = Task.Factory.StartNew(() => {
// do some work
if (token.IsCancellationRequested) {
// Clean up as needed here ....
}
token.ThrowIfCancellationRequested();
}, token);
要取消任务
请调用tokenSource
上的cancel()
如果您的任务调用任何同步方法来执行任何类型的I/O或其他需要时间的未指定操作,那么没有通用的方法来“取消”它
根据您尝试“取消”它的方式,可能会发生以下情况之一:
- 该操作实际上被取消,并且它所使用的资源处于稳定状态(您很幸运!)
- 该操作实际上被取消,并且它所使用的资源处于不一致的状态(以后可能会导致各种问题)
- 该操作将继续,并且可能会干扰其他代码正在执行的任何操作(以后可能会导致各种问题)
- 操作失败或导致进程崩溃
- 你不知道会发生什么,因为它是没有记录的
在一些有效的场景中,您可以并且可能应该使用其他答案中描述的通用方法之一取消任务。但是如果你在这里是因为你想中断一个特定的同步方法,最好看看该方法的文档,看看是否有方法中断它,如果它有一个“timeout”参数,或者如果有可中断的变化。为什么不使用取消api?什么是取消api?检查我的答案我放了一些关于iTunesful的链接阅读:这不允许你只从“外部”请求取消吗?委托人是否关注基于令牌的请求并实际抛出或继续工作而不取消,这不是由委托人决定的吗?正确,委托人通过检查属性上的IsCancellationRequest
来决定是否对请求采取行动。这很有趣,因为这里的帮助文本似乎说的是相反的:“等待任务在指定的毫秒数内完成执行。”不确定我是否理解这一点。@Michael如果传递到Wait
的时间到期,它将返回,即使任务尚未完成。在这种超时情况下,任务将继续执行,直到完成为止(随后的Wait
将返回为已完成)。我注意到cts.Token
也被传递给Wait()
方法。我在微软的文档中发现了一条注释:“将cancellationToken对象传递给此方法只允许根据某些条件取消等待。”最后一行看起来更漂亮,如下所示:cts.CancelAfter(3000);newTask.Wait(cts.Token)代码>