In Sim#, a process is a method that returns an IEnumerable<Event>. You use the yield return keyword to trigger events like timeouts or resource requests. This allows you to model complex logic with minimal boilerplate.
Example of an m/m/1 queuing system:
using static SimSharp.Distributions;
ExponentialTime ARRIVAL = EXP(TimeSpan.FromSeconds(...));
ExponentialTime PROCESSING = EXP(TimeSpan.FromSeconds(...));
TimeSpan SIMULATION_TIME = TimeSpan.FromHours(...);
// A process that generates items
IEnumerable<Event> MM1Q(Simulation env, Resource server) {
while (true) {
yield return env.Timeout(ARRIVAL);
env.Process(Item(env, server));
}
}
// A process representing an item moving through the system
IEnumerable<Event> Item(Simulation env, Resource server) {
using (var s = server.Request()) {
yield return s; // Wait for resource
yield return env.Timeout(PROCESSING); // Wait for processing time
Console.WriteLine("Duration {0}", env.Now - s.Time);
}
}
void RunSimulation() {
var env = new Simulation(randomSeed: 42);
var server = new Resource(env, capacity: 1) {
QueueLength = new TimeSeriesMonitor(env, collect: true)
};
env.Process(MM1Q(env, server));
env.Run(SIMULATION_TIME);
Console.WriteLine(server.QueueLength.Summarize());
}
using static SimSharp.Distributions;
ExponentialTime ARRIVAL = EXP(TimeSpan.FromSeconds(...));
ExponentialTime PROCESSING = EXP(TimeSpan.FromSeconds(...));
TimeSpan SIMULATION_TIME = TimeSpan.FromHours(...);
IEnumerable<Event> MM1Q(Simulation env, Resource server) {
while (true) {
yield return env.Timeout(ARRIVAL);
env.Process(Item(env, server));
}
}
IEnumerable<Event> Item(Simulation env, Resource server) {
using (var s = server.Request()) {
yield return s;
yield return env.Timeout(PROCESSING);
Console.WriteLine("Duration {0}", env.Now - s.Time);
}
}
void RunSimulation() {
var env = new Simulation(randomSeed: 42);
var server = new Resource(env, capacity: 1) {
QueueLength = new TimeSeriesMonitor(env, collect: true)
};
env.Process(MM1Q(env, server));
env.Run(SIMULATION_TIME);
Console.WriteLine(server.QueueLength.Summarize());
}