/// <summary> /// Initializes a new instance of the <see cref="TimerInfo"/> class. /// </summary> /// <param name="ownerId">The id of the actor that owns this timer.</param> /// <param name="dueTime">The amount of time to wait before sending the first timeout event.</param> /// <param name="period">The time interval between timeout events.</param> /// <param name="customEvent">Optional custom event to raise instead of a default TimerElapsedEvent.</param> internal TimerInfo(ActorId ownerId, TimeSpan dueTime, TimeSpan period, TimerElapsedEvent customEvent) { this.Id = Guid.NewGuid(); this.OwnerId = ownerId; this.DueTime = dueTime; this.Period = period; this.CustomEvent = customEvent; }
/// <summary> /// Initializes a new instance of the <see cref="ActorTimer"/> class. /// </summary> /// <param name="info">Stores information about this timer.</param> /// <param name="owner">The actor that owns this timer.</param> public ActorTimer(TimerInfo info, Actor owner) { this.Info = info; this.Owner = owner; this.TimeoutEvent = this.Info.CustomEvent; if (this.TimeoutEvent is null) { this.TimeoutEvent = new TimerElapsedEvent(this.Info); } else { this.TimeoutEvent.Info = this.Info; } // To avoid a race condition between assigning the field of the timer // and HandleTimeout accessing the field before the assignment happens, // we first create a timer that cannot get triggered, then assign it to // the field, and finally we start the timer. this.InternalTimer = new Timer(this.HandleTimeout, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan); this.InternalTimer.Change(this.Info.DueTime, Timeout.InfiniteTimeSpan); }