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);
storageSystem1.PackInputRequested += StorageSystem_PackInputRequested;
storageSystem1.Connect("localhost", 12345);
storageSystem1.Subscribe();
var storageSystem2 = new RowaStorageSystem(2);
storageSystem2.PackInputRequested += StorageSystem_PackInputRequested;
storageSystem2.Connect("localhost", 12345);
storageSystem2.Subscribe();
Task.Run(() => TriggerEventWithDelay(storageSystem1));
Task.Run(() => TriggerEventWithDelay(storageSystem2));
private static void TriggerEventWithDelay(RowaStorageSystem 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}");