【发布时间】:2018-09-09 01:57:55
【问题描述】:
我创建了一个多任务程序。这个程序有大约 20 个主要任务,每个任务都会调用一些子任务来操作文件 I/O。我希望每个主要任务每 500 毫秒定期重复一次,所以我输入了代码 Task.Delay(500)。
问题是 Task.Delay 有时会延迟超过 500 毫秒。有一种情况会延迟超过 3 秒。 我该如何解决?
原来的程序太大了,我在下面创建了一个示例程序。 (1) 如果 Task.Delay 开启,则会发生过延迟。 (2) 如果 Thead.Sleep 开启,则不会发生过延迟。
ThreadPool.SetMinThreads() 似乎无法解决它。
谢谢。
class Program
{
const int DELAY_TIME = 500;
const int TASKS = 100;
const int WAITS = 100;
const int WARNING_THRESHOLD = 100;
static void Main(string[] args)
{
//ThreadPool.SetMinThreads(workerThreads: 200, completionPortThreads: 200);
Console.WriteLine("*** Start...");
Test();
Console.WriteLine("*** Done!");
Console.ReadKey();
}
private static void Test()
{
List<Task> tasks = new List<Task>();
for (int taskId = 0; taskId < TASKS; taskId++)
{
tasks.Add(DelaysAsync(taskId));
}
Task.WaitAll(tasks.ToArray());
}
static async Task DelaysAsync(int taskId)
{
await Task.Yield();
Stopwatch sw = new Stopwatch();
for (int i = 0; i < WAITS; i++)
{
sw.Reset();
sw.Start();
await Task.Delay(DELAY_TIME).ConfigureAwait(false); // (1)
//Thread.Sleep(DELAY_TIME); // (2)
sw.Stop();
Console.Write($"Task({taskId})_iter({i}) Elapsed={sw.ElapsedMilliseconds}");
if (sw.ElapsedMilliseconds > DELAY_TIME + WARNING_THRESHOLD)
{
Console.WriteLine(" *********** Too late!! ************");
}
else
{
Console.WriteLine();
}
}
}
}
【问题讨论】:
-
听起来可用的线程数量可能有限。
ThreadPool.GetAvailableThreads你有什么价值? -
感谢您的评论。我试过
ThreadPool.GetAvailableThreads并得到workerThreads=2047, completionPortThreads=1000。 -
我的可用线程较少,机器较旧。可能是调试器,我没有调试就运行了,没有遇到你遇到的情况
-
我在 Release 和 Debug 上运行它以得到相同的结果。
标签: c# .net asynchronous async-await task-parallel-library