使用Task.Delay()的成本是多少?

Ant*_*rov 15 c# multithreading asynchronous async-await

我正在考虑在具有事件驱动逻辑的MMO游戏服务器中使用C#async\await.让我们假设有数千个实体在已知持续时间内完成一些工作.所以我想调用Time.Delay()我的每个游戏对象.(这是对常见的无限循环的对立方法,Update()对每个游戏对象都有一些调用.)

有谁知道如何Task.Delay()实施?它是否使用计时器?系统资源是否很重?

是否可以产生数千个同时Task.Delay()调用?

It'*_*ie. 19

Task.Delay 实施如下:

public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken)
{
  //error checking
  Task.DelayPromise delayPromise = new Task.DelayPromise(cancellationToken);
  if (cancellationToken.CanBeCanceled)
    delayPromise.Registration = cancellationToken.InternalRegisterWithoutEC((Action<object>) (state => ((Task.DelayPromise) state).Complete()), (object) delayPromise);
  if (millisecondsDelay != -1)
  {
    delayPromise.Timer = new Timer((TimerCallback) (state => ((Task.DelayPromise) state).Complete()), (object) delayPromise, millisecondsDelay, -1);
    delayPromise.Timer.KeepRootedWhileScheduled();
  }
  return (Task) delayPromise;
}
Run Code Online (Sandbox Code Playgroud)

它肯定使用计时器.它们被用在一个叫做的类中DelayPromise.这是实现:

private sealed class DelayPromise : Task<VoidTaskResult>
{
  internal readonly CancellationToken Token;
  internal CancellationTokenRegistration Registration;
  internal Timer Timer;

  internal DelayPromise(CancellationToken token)
  {
    this.Token = token;
  }

  internal void Complete()
  {
    if (!(this.Token.IsCancellationRequested ? this.TrySetCanceled(this.Token) : this.TrySetResult(new VoidTaskResult())))
      return;
    if (this.Timer != null)
      this.Timer.Dispose();
    this.Registration.Dispose();
  }
}
Run Code Online (Sandbox Code Playgroud)

它确实使用了计时器,但对我来说似乎并不担心.计时器只是回调完整的方法,它的作用是检查它是否被取消,如果取消它,否则只返回一个结果.对我来说似乎很好.

  • .NET Timer实现包装Win32计时器队列,该队列是一个在线程池上触发事件的增量队列.更多信息:https://msdn.microsoft.com/en-us/library/ms686796%28v=VS.85%29.aspx (5认同)
  • 我相信实际(非托管)实现确实使用了delta队列.尽管如此,如果你有许多"延迟"调用,你将会产生大量垃圾,而且它不是最有效的解决方案.如果你的"成千上万的实体"每秒都在做几件事,我会考虑其他选择. (4认同)