20

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

有人知道如何Task.Delay()实施吗?是否使用计时器?是否占用系统资源?

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

4

1 回答 1

23

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

它肯定使用计时器。它们用于一个名为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();
  }
}

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

于 2013-06-29T09:58:25.227 回答