【发布时间】:2020-08-12 16:26:20
【问题描述】:
在 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 ThreadID:12 时间延迟:582.6348
Id:22 时间:23:04:01 974 ThreadID:14 时间延迟:552.7234000000001
Id:42 时间:23:04:04 967 ThreadID: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(100)将等待至少 100ms。无法保证调度程序何时会在您等待之后开始运行延续。 -
您有fire and forgets 和blocking calls 的混合体(到
Wait)。结果不足为奇。 -
基本上你的问题是“如果我试图将系统推到它崩溃的地步,它确实会崩溃。为什么会这样?” - 创建大量异步操作确实需要大量时间来处理它们,仅处理返回可能需要很长时间......
-
DoSomeThing是一种异步方法(顺便说一句,您应该在其名称中添加Async 后缀),但您并没有等待它。为什么?
标签: c# multithreading async-await task delay