【发布时间】:2019-05-30 22:46:03
【问题描述】:
我很难理解这个简单程序中发生了什么。
在下面的示例中,我有一个任务工厂,它使用 ParallelExtensionsExtras 中的 LimitedConcurrencyLevelTaskScheduler,maxDegreeOfParallelism 设置为 2。
然后我启动 2 个任务,每个任务调用一个异步方法(例如异步 Http 请求),然后获取等待者和完成任务的结果。
问题似乎是Task.Delay(2000) 永远不会完成。如果我将 maxDegreeOfParallelism 设置为 3(或更大),它就完成了。但是在 maxDegreeOfParallelism = 2 (或更少)的情况下,我的猜测是没有可用的线程来完成任务。这是为什么呢?
它似乎与 async/await 相关,因为如果我删除它并简单地在 DoWork 中执行 Task.Delay(2000).GetAwaiter().GetResult() 它可以完美运行。 async/await 是否以某种方式使用父任务的任务调度程序,或者它是如何连接的?
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Threading.Tasks.Schedulers;
namespace LimitedConcurrency
{
class Program
{
static void Main(string[] args)
{
var test = new TaskSchedulerTest();
test.Run();
}
}
class TaskSchedulerTest
{
public void Run()
{
var scheduler = new LimitedConcurrencyLevelTaskScheduler(2);
var taskFactory = new TaskFactory(scheduler);
var tasks = Enumerable.Range(1, 2).Select(id => taskFactory.StartNew(() => DoWork(id)));
Task.WaitAll(tasks.ToArray());
}
private void DoWork(int id)
{
Console.WriteLine($"Starting Work {id}");
HttpClientGetAsync().GetAwaiter().GetResult();
Console.WriteLine($"Finished Work {id}");
}
async Task HttpClientGetAsync()
{
await Task.Delay(2000);
}
}
}
提前感谢您的帮助
【问题讨论】:
-
您可以放心地假定“LimitedConcurrency”就是它所说的那样。灵活的无限制任务调度程序以建设性的方式处理死锁错误,它确实将并发级别提高到超过最佳水平。就像 ThreadPool 和 Task 一样。使用 Debug > Windows > Threads 查看发生了什么。
标签: c# .net async-await task