gpt4 book ai didi

c# - Task.WaitAll 方法 (Task[], Int32) 过期时不释放线程

转载 作者:行者123 更新时间:2023-12-01 18:44:56 25 4
gpt4 key购买 nike

Task.WaitAll 方法 (Task[], Int32) 过期时不会释放线程。

我正在使用.net框架4.0。我发现Task.WaitAll方法过期后仍然占用线程。

我编写下面的代码来测试它。

static void Main(string[] args)
{
printThreadCount("start");
Task[] tasks = new Task[5];
for (int i = 0; i < 5; i++)//create tasks
{
Task t = new Task(() =>
{
Thread.Sleep(30000);
Console.WriteLine(DateTime.Now.ToString() + "task finish");
}
);

tasks[i] = t;
}

for (int i = 0; i < 5; i++)
{
tasks[i].Start();//start 1 task per second
Thread.Sleep(1000);
printThreadCount("start 1 task per second");
}

printThreadCount("before waitall");
Task.WaitAll(tasks, 10000);

printThreadCount("after waitall 10s");
Thread.Sleep(5000);
printThreadCount("sleep 5s");
Thread.Sleep(5000);
printThreadCount("sleep 5s");
Thread.Sleep(5000);
printThreadCount("sleep 5s");
Thread.Sleep(5000);
printThreadCount("sleep 5s");

Console.WriteLine("end");
}

static void printThreadCount(string title)
{
int MaxWorkerThreads, MaxIOThreads;
ThreadPool.GetMaxThreads(out MaxWorkerThreads, out MaxIOThreads);
int AvailableWorkerThreads = 0;
int AvailableIOThreads = 0;
ThreadPool.GetAvailableThreads(out AvailableWorkerThreads, out AvailableIOThreads);

Console.WriteLine();
Console.WriteLine("*****************" + title + "********************");

Console.WriteLine("active Worker Threads count:" + (MaxWorkerThreads - AvailableWorkerThreads));
Console.WriteLine("active IO Threads count:" + (MaxIOThreads - AvailableIOThreads));
}

我创建了5个任务,每秒启动1个任务,每个任务将持续30秒。 Task.WaitAll 将等待它们 10 秒。理想情况下,当 waitall 过期时,所有这些都超时。但他们仍然占据着线程。足够的时间后,所有任务将完成并运行 Console.WriteLine(DateTime.Now.ToString() + "task finish"),然后释放所有线程。

结果如下:

the result of above code

这对我来说不是正常行为。我希望时间结束后所有任务都被终止。waitall时间到期后如何杀死它们?

最佳答案

I want all the task are killed when time is over.

正如您从 documentation 中看到的那样, Task.WaitAll 不会终止任务。它只是等待他们完成最多 10 秒。如果它们没有在 10 秒内完成,该方法将返回并且不执行任何其他操作。

如果您想取消任务,您应该使用 CancellationToken。请参阅Cancellation in Managed Threads

//create a cancellation token that will cancel itself after 3secs
int timeout = 3000;
var source = new CancellationTokenSource(timeout);
var token = source.Token;

List<Task> tasks = new List<Task>();
for (int i = 0; i < 5; i++)
{
Task t = Task.Run(async () =>
{
//wait for 30 secs OR until cancellation is requested
await Task.Delay(30000, token);
Console.WriteLine(DateTime.Now.ToString() + "task finish");
});
tasks.Add(t);
}

printThreadCount("before waitall");
try
{
Task.WaitAll(tasks.ToArray());
}
catch(AggregateException ex)
{
foreach (var e in ex.Flatten().InnerExceptions)
Console.WriteLine(e.Message);
}
printThreadCount("after waitall");

关于c# - Task.WaitAll 方法 (Task[], Int32) 过期时不释放线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24723338/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com