我正在考虑在具有事件驱动逻辑的 MMO 游戏服务器中使用 C# async\await。让我们假设有数千个实体在做一些已知持续时间的工作。所以我想Time.Delay()
为我的每一个游戏对象调用。Update()
(这是对每个游戏对象都有调用的常见无限循环的相反方法。)
有人知道如何Task.Delay()
实施吗?是否使用计时器?是否占用系统资源?
可以同时产生数千个Task.Delay()
调用吗?
我正在考虑在具有事件驱动逻辑的 MMO 游戏服务器中使用 C# async\await。让我们假设有数千个实体在做一些已知持续时间的工作。所以我想Time.Delay()
为我的每一个游戏对象调用。Update()
(这是对每个游戏对象都有调用的常见无限循环的相反方法。)
有人知道如何Task.Delay()
实施吗?是否使用计时器?是否占用系统资源?
可以同时产生数千个Task.Delay()
调用吗?
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();
}
}
它确实使用了计时器,但对我来说似乎并不担心。计时器只是回调完成方法,它的作用是检查它是否被取消,如果是则取消它,否则只返回一个结果。对我来说似乎很好。