2017-09-27 42 views
-1

只是想了解为什么SleepAsyncB不使用线程:TaskCompletionSource具有更好的可伸缩性?

的SleepAsyncA方法使用一个线程从线程池,而 睡觉。然而,第二种方法具有完全不同的实现,在等待 定时器运行时不会占用线程。第二种方法为您提供可扩展性。

我想方法SleepAsyncB通过Win API创建Timer并给出回调。但我想Timer本身是独立的线程?

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; 
     } 
+0

这是从一本书吗?我会使用(并等待)Task.Delay ... https://msdn.microsoft.com/en-us/magazine/jj991977.aspx =>请参见图5 – Fildor

+0

关于您的问题:SleepAsyncA阻止TP线程为其整个运行时间。 SleepAsyncB不会因为Timer可以使用不需要实际线程被阻塞的本机功能。 _“但我想Timer本身是独立的线程?” - - 不,它不是。 – Fildor

回答

0

SleepAsyncA将强制线程从TPL线程池睡的millisecondsTimeout时间,有效地渲染线程不可用。

SleepAsyncB,通过使用定时器,延迟了一段代码以后执行,而不是阻塞线程,直到millisecondsTimeout过去。这不使用线程,因为这是由OS提供的本地功能。

而且,@Fildor已经在评论中已经指出,SleepAsyncB代码可以通过一个单一的电话更换,以Task.Delay(millisecondsTimeout)(假设定时器是System.Threading.Timer

+0

我认为混乱是因为OP认为'Timer'内部需要一个Tread--当然这是不正确的。 – Fildor

+2

这可能对每个人都不明显,而且我认为有一个线程(由CLR管理)负责循环TimerQueue并将所有已用计时器分派给ThreadPool,但此线程始终存在,而您没有有效地使用或阻止它(虽然你的陈述,“计时器本身不是一个单独的线程”可能被认为是真的) –

+0

这就是我想说的。 – Fildor