任务可用的最大线程数
Maximum number of Threads available to Tasks
我正在尝试了解 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 秒后停止)。我附上了下面的输出。
我想知道的:
- 有人知道这个特定示例中发生了什么吗?
- 可用线程的限制是否小到足以在此处产生影响?
- 我认为异步任务不能保证立即开始,但这里似乎还有一些其他确定性过程在进行,这是我没有预料到的。有人知道那是什么吗?
编辑
请注意,此问题不是询问可以 运行 (Max tasks in TPL?) 的最大任务数,而是询问当 运行ning 尽可能少时效果如何作为5个任务。我的印象是默认线程池包含的线程比这多得多。
原来我看到的问题与线程池大小有关。这显然最初设置为机器的核心数 (https://msdn.microsoft.com/en-us/library/system.threading.threadpool.getminthreads%28v=vs.110%29.aspx)。
可以增加,这样做意味着更多的任务最初是同时运行(https://msdn.microsoft.com/en-us/library/system.threading.threadpool.setminthreads%28v=vs.110%29.aspx)
我正在尝试了解 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 秒后停止)。我附上了下面的输出。
我想知道的:
- 有人知道这个特定示例中发生了什么吗?
- 可用线程的限制是否小到足以在此处产生影响?
- 我认为异步任务不能保证立即开始,但这里似乎还有一些其他确定性过程在进行,这是我没有预料到的。有人知道那是什么吗?
编辑
请注意,此问题不是询问可以 运行 (Max tasks in TPL?) 的最大任务数,而是询问当 运行ning 尽可能少时效果如何作为5个任务。我的印象是默认线程池包含的线程比这多得多。
原来我看到的问题与线程池大小有关。这显然最初设置为机器的核心数 (https://msdn.microsoft.com/en-us/library/system.threading.threadpool.getminthreads%28v=vs.110%29.aspx)。
可以增加,这样做意味着更多的任务最初是同时运行(https://msdn.microsoft.com/en-us/library/system.threading.threadpool.setminthreads%28v=vs.110%29.aspx)