【发布时间】:2021-01-27 08:15:26
【问题描述】:
我正试图在一段时间后停止 C# 中的任务。
对于我的代码:Task.Delay().Wait() 应该只代表 Task 所做的一些工作。
我的代码:
public static void Main()
{
Console.WriteLine("starting app");
try
{
Console.WriteLine("before");
DoStuff(1000);
Console.WriteLine("after");
}
catch
{
Console.WriteLine("TIMEOUT");
}
Console.WriteLine("Main finished wait 5 sec now");
Task.Delay(10000).Wait();
Console.WriteLine("Closing app now");
}
public static async Task DoStuff(int time)
{
Task real = Task.Run(()=>
{
Task.Delay(2000).Wait();
Console.WriteLine("Task Running");
Task.Delay(2000).Wait();
Console.WriteLine("still running");
Task.Delay(2000).Wait();
Console.WriteLine("Not dead yet");
Task.Delay(1000).Wait();
Console.WriteLine("Task done");
Task.Delay(5000);
});
bool success = real.Wait(time);
if ( success )
{
Console.WriteLine("Task finished in time");
await real;
}
else
{
Console.WriteLine("Task did not finish");
real.Dispose();
throw new TimeoutException("The task took too long");
}
}
我已经尝试使用取消令牌,但我没有循环来检查每次迭代的令牌。所以我尝试用Task.Wait(time) 来做这件事,我得到了正确的信息,但是在使用Task.Dispose() 方法后任务并没有停止。我得到以下输出:
所以我得到了当前的输出,但任务继续在后面运行..关于如何解决这个问题的任何想法?
【问题讨论】:
-
在
DoStuff的所有任务上调用Wait是非常错误的 -
@TheodorZoulias 鉴于每个
.Wait()都也严重损坏,我不确定这是否值得特别注意:) -
@MarcGravell “可怕”是一个强词。我称之为“不是最佳的”。 ??????
-
Alex 所以如果我理解正确你想以非合作方式取消
DoStuff异步方法?如果是这种情况,那么简短的回答是“你不能”。 .NET 中的取消是cooperative。只有aborting threads 可以进行非合作取消,这很危险,因为它会破坏程序的内部状态,甚至在较新版本的 .NET 中也不支持。 -
您无法真正取消并非设计为取消的
Task。您可以做的是取消等待任务。换句话说,任务将继续运行,但您将忽略它,您的代码不会等待它完成。如果您对此感到满意,您可以查看此question 以获取解决方案。有人发布了一个方便的WaitOrCancel方法,您可以使用。
标签: c# asynchronous async-await task