using System.Threading.Tasks;
public interface IInputRequest { }
public class InputRequest : IInputRequest { }
public delegate void PackInputRequestedEventHandler(IStorageSystem sender, IInputRequest request);
public interface IStorageSystem
int SubscriberId { get; }
event PackInputRequestedEventHandler PackInputRequested;
void Connect(string host, ushort port);
public class RowaStorageSystem : IStorageSystem
public int SubscriberId { get; private set; }
private static RowaStorageSystem latestSubscriber;
public event PackInputRequestedEventHandler PackInputRequested;
public RowaStorageSystem(int subscriberId)
SubscriberId = subscriberId;
public void Connect(string host, ushort port)
Console.WriteLine($"Connected to {host}:{port} with SubscriberId {SubscriberId}");
public void RequestPackInput()
if (latestSubscriber == this)
PackInputRequested?.Invoke(this, new InputRequest());
private static Random random = new Random();
public static void Main()
var storageSystem1 = new RowaStorageSystem(1);
var storageSystem2 = new RowaStorageSystem(2);
storageSystem1.PackInputRequested += StorageSystem_PackInputRequested;
storageSystem2.PackInputRequested += StorageSystem_PackInputRequested;
Task.Run(() => ConnectAndSubscribeWithDelay(storageSystem1, "localhost", 12345));
Task.Run(() => ConnectAndSubscribeWithDelay(storageSystem2, "localhost", 12345));
Task.Run(() => TriggerEventWithDelay(storageSystem1));
Task.Run(() => TriggerEventWithDelay(storageSystem2));
private static void ConnectAndSubscribeWithDelay(RowStorageSystem storageSystem, string host, ushort port)
int delay = random.Next(1000, 5000);
storageSystem.Connect(host, port);
storageSystem.Subscribe();
private static void TriggerEventWithDelay(RowStorageSystem storageSystem)
int delay = random.Next(1000, 5000);
storageSystem.RequestPackInput();
private static void StorageSystem_PackInputRequested(IStorageSystem sender, IInputRequest request)
Console.WriteLine($"Event received from StorageSystem {sender.SubscriberId} on thread {Thread.CurrentThread.ManagedThreadId}");