我正在努力理解C#中的异步等待功能。我编写了以下代码以异步运行多个任务 - 目前,它们只是在一定时间后引发事件。
public class Program
{
public static Stopwatch Watch = new Stopwatch();
public static void Main(string[] args)
{
AsyncClass asyncClass = new AsyncClass();
asyncClass.WaitSecondsAsyncCompleted += asyncClass_WaitSecondsAsyncCompleted;
List<Task> tasks = new List<Task>();
Watch.Start();
for (int i = 1; i < 6; i++)
{
tasks.Add(asyncClass.WaitSecondsAsync(i, Watch));
}
Task.WaitAll(tasks.ToArray());
Console.ReadLine();
}
private static void asyncClass_WaitSecondsAsyncCompleted(int i)
{
Console.WriteLine("{1} : Async Method Called: waited for {0} seconds", i, Watch.ElapsedMilliseconds);
}
}
public class AsyncClass
{
public event Action<int> WaitSecondsAsyncCompleted;
public async Task WaitSecondsAsync(int x, Stopwatch watch)
{
await Task.Run(() =>
{
Thread.Sleep(x * 500);
});
if (WaitSecondsAsyncCompleted != null)
{
WaitSecondsAsyncCompleted(x);
}
}
}
我期望一个任务每半秒钟运行一次,但实际情况并非如此。前四个任务按时完成,但最后一个任务会多延迟半秒钟:
这看起来很奇怪——我唯一想到的就是任务可用线程数量有限,限制很小,所以第五个任务必须等待第一个任务完成才能开始。
我增加了一些额外的输出并增加了任务数量,试图获得更多信息,但我几乎无法理解它——输出似乎是确定性的,一些线程被重用,但也使用了新的线程。任务完成的延迟时间似乎也继续增长(例如对于任务10,我希望在5秒后完成,但实际上在8秒后停止)。以下是输出:
我想知道:
- 有人知道这个特定示例中发生了什么吗?
- 线程数的限制是否足够小以在这里产生影响?
- 我认为异步任务不能保证立即启动,但这里似乎还有其他确定性过程,我没有预料到。 有人知道是什么吗?
注意,此问题并不涉及可以运行的最大任务数(TPL中的最大任务数?),而是运行仅有5个任务时如何看到效果。 我曾以为默认的线程池包含更多线程。
Task.WaitAll(tasks.ToArray());
等待任务完成,但据我所知,您并没有 等待 任务。 - Maarten