C# TaskCompletionSource是否具有更好的可扩展性?

C# TaskCompletionSource是否具有更好的可扩展性?,c#,multithreading,C#,Multithreading,只是想了解为什么SleepAsyncB不使用线程: SleepAsyncA方法在 睡觉。然而,第二种方法具有完全不同的性能 不同的实现,在等待时不占用线程 要运行的计时器。第二种方法提供了可伸缩性 我假设方法SleepAsyncB通过WinAPI创建计时器并给出回调。但我想定时器本身是独立的线程 public static Task SleepAsyncA(int millisecondsTimeout) { return Task.Run(() =>

只是想了解为什么SleepAsyncB不使用线程:

SleepAsyncA方法在 睡觉。然而,第二种方法具有完全不同的性能 不同的实现,在等待时不占用线程 要运行的计时器。第二种方法提供了可伸缩性

我假设方法SleepAsyncB通过WinAPI创建计时器并给出回调。但我想定时器本身是独立的线程

public static Task SleepAsyncA(int millisecondsTimeout)
        {
            return Task.Run(() =>
            {
                Thread.Sleep(millisecondsTimeout);

            });
        }

        public static Task SleepAsyncB(int millisecondsTimeout)
        {
            TaskCompletionSource<bool> tcs = null;
            var t = new Timer(delegate { tcs.TrySetResult(true); }, null, -1, -1);
            tcs = new TaskCompletionSource<bool>(t);
            t.Change(millisecondsTimeout, -1);
            return tcs.Task;
        }
公共静态任务SleepAsyncA(int毫秒)
{
返回任务。运行(()=>
{
睡眠(毫秒刺激);
});
}
公共静态任务SleepAsyncB(整数毫秒)
{
TaskCompletionSource tcs=null;
var t=新计时器(委托{tcs.TrySetResult(true);},null,-1,-1);
tcs=新任务完成源(t);
t、 变化(毫秒刺激,-1);
返回tcs.Task;
}

SleepAsyncA
将强制TPL线程池中的线程在
毫秒时间段内休眠,从而有效地使该线程无法使用

SleepAsyncB
通过使用计时器延迟稍后执行的一段代码,而不是阻塞一个线程,直到
毫秒间隔
过去。这不使用线程,因为这是操作系统提供的本机功能


此外,正如@Fildor在评论中所述,
SleepAsyncB
代码可以被对
Task.Delay(毫秒计时)
的单个调用所取代(假设计时器是
System.Threading.Timer

这是从书中得到的吗?我会使用(并等待)任务。延迟…=>关于您的问题,请参见图5:SleepAsyncA在其整个运行时阻塞了一个TP线程。SleepAsyncB没有,因为计时器可以使用不需要阻塞实际线程的本机功能。“但我认为计时器本身是独立的线程?”-不,不是。我认为混淆是因为OP认为
Timer
需要一个内部线程-这当然是不正确的。这可能不是每个人都清楚的,而且,我认为有一个线程(由CLR管理)它负责循环一个TimerQueue,并将所有经过的计时器分派到线程池,但这个线程始终存在,并且您没有有效地使用或阻止它(尽管您关于“计时器本身不是一个单独的线程”的陈述可能被认为是真实的),这就是我想要说的。