等待任务.Delay()花费了太多时间



在C#中,我有一个例子:

public async static Task TaskTest(int i)
{
await Task.Delay(1);
Console.WriteLine($"{i}. {DateTime.Now.ToString("HH:mm:ss fff")} " +
$"ThreadId:{Thread.CurrentThread.ManagedThreadId} Start");
int count = 1;
while (true)
{
DoSomeThing(count);
var stopWatch = new Stopwatch();
stopWatch.Start();
await Task.Delay(100);
stopWatch.Stop();
if (stopWatch.Elapsed.TotalMilliseconds > 200)
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Id:{count} Time:{DateTime.Now.ToString("HH:mm:ss fff")} " +
$"ThreadID:{Thread.CurrentThread.ManagedThreadId} Time Delay:{stopWatch.Elapsed.TotalMilliseconds }");
Console.ForegroundColor = ConsoleColor.White;
count++;
}
}
public async static Task DoSomeThing(int index)
{
await Task.Delay(1);
Task.Delay(1000).Wait();
}
private static void Main(string[] args)
{
int i = 1;
while (i < 2)
{
TaskTest(i);
Task.Delay(1).Wait();
i++;
}
Console.ReadKey();
}

这是我的结果结果

Id:8时间:23:03:59 972线程Id:12时间延迟:582.6348

Id:22时间:23:04:01 974线程Id:14时间延迟:552.7234000000001

Id:42时间:23:04:04 967线程Id:8时间延迟:907.3214

我不知道为什么任务有时会延迟超过200毫秒。

更新:感谢所有回复。我更新我的代码以使用Thread和Thread.Sleep((以及Task.Run((。我将永远运行的线程数量增加到500个。我在30分钟内进行了测试,500个线程的睡眠时间从未超过200ms。你认为这是坏代码吗?请留言评论!非常感谢!

public static void TaskTest(object i)
{
Console.WriteLine($"{i} Start");
int count = 1;
while (true)
{
// Open Task to do work
Task.Run(() => { DoSomeThing(count); });
var stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(100);
stopWatch.Stop();
if (stopWatch.Elapsed.TotalMilliseconds > 200)
{
Console.WriteLine($"Id:{count} Time:{DateTime.Now.ToString("HH:mm:ss fff")} " +
$"ThreadID:{Thread.CurrentThread.ManagedThreadId} Time Delay:{stopWatch.Elapsed.TotalMilliseconds }");
}
count++;
}
}
public static void DoSomeThing(int index)
{
Thread.Sleep(1000); // Time spent complete work
}
private static void Main(string[] args)
{
int i = 0;
while (i < 500)
{
// Open Thread for TaskTest
Thread tesThread = new Thread(TaskTest);
tesThread.IsBackground = true;
tesThread.Start(i);
i++;
}
Console.WriteLine("Finish init");
Console.ReadKey();
}

Task.Delay与任何其他多线程睡眠函数一样,将其运行的线程返回到系统(或者在线程池的情况下,返回到线程池调度程序(,要求在指定的时间后重新调度。

这是你唯一的保证,它将至少等待指定的金额。它实际等待的时间在很大程度上取决于你的线程池负载(你在那里延迟了很多任务(、一般的系统负载(在任何给定的时间点,在一个普通的计算机操作系统上都有数千个线程需要调度(和你的CPU&操作系统快速调度线程的能力(在Windows中,请参阅timeBeginPeriod(。

长话短说,如果准确的时机对你很重要,不要放弃你的思路。

最新更新