如何解决等待Task.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();
}
这是我的结果 Result
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
我不知道为什么Task有时会延迟200毫秒以上。
更新: 谢谢你的回答。 我更新代码以使用Thread和Thread.Sleep()和Task.Run()。我将永远运行的线程数增加到500。我在30分钟内进行了测试,并且500个线程的睡眠时间都不会超过200毫秒。 您认为这是错误的代码吗? 请发表评论! 非常感谢!
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和OS快速调度线程的能力(在Windows中,请查看timeBeginPeriod
)。
长话短说,如果精确的时机对您很重要,请不要放弃您的话题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。