/// <summary> /// Raises an event internally and returns from the execution context. /// </summary> /// <param name="e">Event</param> protected void Raise(Event e) { // If the event is null, then report an error and exit. this.Assert(e != null, $"Monitor '{this.GetType().Name}' is raising a null event."); EventInfo raisedEvent = new EventInfo(e, new EventOriginInfo( base.Id, this.GetType().Name, Machine.GetQualifiedStateName(this.CurrentState))); base.Runtime.NotifyRaisedEvent(this, raisedEvent, false); this.HandleEvent(e); }
/// <summary> /// Sends an asynchronous event to a machine. /// </summary> /// <param name="sender">Sender machine</param> /// <param name="mid">MachineId</param> /// <param name="e">Event</param> /// <param name="isStarter">Is starting a new operation</param> internal virtual void Send(AbstractMachine sender, MachineId mid, Event e, bool isStarter) { EventOriginInfo originInfo = null; if (sender != null && sender is Machine) { originInfo = new EventOriginInfo(sender.Id, (sender as Machine).GetType().Name, Machine.GetQualifiedStateName((sender as Machine).CurrentState)); } EventInfo eventInfo = new EventInfo(e, originInfo); Machine machine = null; if (!this.MachineMap.TryGetValue(mid.Value, out machine)) { return; } bool runHandler = false; machine.Enqueue(eventInfo, ref runHandler); if (!runHandler) { return; } Task task = new Task(() => { try { machine.RunEventHandler(); } catch (Exception) { if (this.Configuration.ThrowInternalExceptions) { throw; } } finally { this.TaskMap.TryRemove(Task.CurrentId.Value, out machine); } }); this.MachineTasks.Add(task); this.TaskMap.TryAdd(task.Id, machine); task.Start(); }