public void CommunicatesWith(TabletWithIo other) { Tablet.OnSnd = v => { NumberOfSentValues++; other.Queue.Add(v); }; Tablet.OnRcv = () => { IsWaitingForReceive = true; if (IsBlocked && other.IsBlocked) { // Deadlocked; both tablets are blocked receiving Tablet.Halt = true; Cts.Cancel(); other.Tablet.Halt = true; other.Cts.Cancel(); return(0); } try { return(Queue.Take(Cts.Token)); } catch (OperationCanceledException) { return(0); } finally { IsWaitingForReceive = false; } }; }
protected override int Part2(string[] input) { var t0 = new TabletWithIo(input, 0); var t1 = new TabletWithIo(input, 1); t0.CommunicatesWith(t1); t1.CommunicatesWith(t0); Task.WhenAll( Task.Run(() => t0.Tablet.Run()), Task.Run(() => t1.Tablet.Run()) ).Wait(); return(t1.NumberOfSentValues); }