具有有限并发性的TaskScheduler会阻塞自身

Ada*_*sko 5 c# multithreading task-parallel-library async-await

我正在尝试使用以下自定义任务计划程序来限制并发Web请求:

我这样使用它:

const int CONCURRENCY_LEVEL = 2;

static void Main()
{
    TaskFactory factory = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(CONCURRENCY_LEVEL));

    Task.WaitAll(new[] { factory.StartNew(() => SomeAction("first")), factory.StartNew(() => SomeAction("second")) });

    Console.WriteLine("All tasks ended");        
    Console.Read();
}

static void SomeAction(string task)
{
    Console.WriteLine(task + " task started");
    Console.WriteLine(AnotherTask(task).Result);
    Console.WriteLine(task + " task ended");
}

static async Task<string> AnotherTask(string task)
{
    return await Task.Run(() =>
    {
        Console.WriteLine(task + " inner task started");
        // imitate web requests
        Thread.Sleep(200);
        Console.WriteLine(task + " inner task ended");
        return "ok";
    });
}
Run Code Online (Sandbox Code Playgroud)

问题是内部任务使用的是my LimitedConcurrencyLevelTaskScheduler而不是默认值TaskScheduler.这导致自我阻塞,输出如下:

second task started
first task started
first inner task started
second inner task started
second inner task ended
first inner task ended
Run Code Online (Sandbox Code Playgroud)

当我更改CONCURRENCY_LEVEL3或更改factoryTask.Factory然后显然一切正常,输出如下:

first task started
second task started
first inner task started
second inner task started
second inner task ended
first inner task ended
ok
second task ended
ok
first task ended
All tasks ended
Run Code Online (Sandbox Code Playgroud)

无法更改代码SomeAction.我还可以做些什么?Microsoft示例中是否存在错误?

Dou*_*las 7

指定TaskCreationOptions.HideScheduler从自定义任务计划程序启动任务的时间:

Task.WaitAll(new[] 
{
   factory.StartNew(() => SomeAction("first"),  TaskCreationOptions.HideScheduler), 
   factory.StartNew(() => SomeAction("second"), TaskCreationOptions.HideScheduler)
});
Run Code Online (Sandbox Code Playgroud)

来自MSDN:

HideScheduler防止环境调度程序被视为已创建任务中的当前调度程序.这意味着在创建的任务中执行的操作StartNewContinueWith将在其中执行的操作将被Default视为当前调度程序.