public List <T> TakeMessagePacket(int timeout) { Packet <T> packet = default; try { MonitorUtilities.EnterUninterruptedly(this.monitor, out var interrupted); packet = this.packets.FirstOrDefault(existingPacket => existingPacket.IsComplete() && !existingPacket.hasWaiter); if (packet == default) { packet = new Packet <T>(packetSize); this.packets.Add(packet); } packet.hasWaiter = true; var timer = new CrossCutting.Timer(timeout); while (true) { if (packet.IsComplete()) { this.packets.Remove(packet); return(packet.messages); } if (timer.IsExpired()) { packet.hasWaiter = false; return(null); } packet.Await(monitor, timer.GetTimeToWait()); } } catch (ThreadInterruptedException) { if (packet.IsComplete()) { this.packets.Remove(packet); Thread.CurrentThread.Interrupt(); return(packet.messages); } packet.hasWaiter = false; throw; } finally { Monitor.Exit(monitor); } }
public bool Transfer(E body, int timeout) { Message <E> message = default; try { MonitorUtilities.EnterUninterruptedly(monitor, out _); message = this.consumers.First(); if (message != default) { this.consumers.Remove(message); Monitor.Exit(this.monitor); message.body = body; message.NotifyWaiter(); return(true); } message = new Message <E>(body, condition: new object()); this.producers.Add(message); var timer = new CrossCutting.Timer(timeout); while (true) { Monitor.Wait(timeout); if (message.body != default) { Monitor.Exit(this.monitor); return(true); } if (timer.IsExpired()) { this.producers.Remove(message); Monitor.Exit(this.monitor); return(false); } } } catch (ThreadInterruptedException) { if (message?.body != default) { Monitor.Exit(this.monitor); Thread.CurrentThread.Interrupt(); return(true); } Monitor.Exit(this.monitor); throw; } }