/// <summary> /// Receives a value over the channel. If no other <see cref="MicroThread"/> is sending data, the receiver will be blocked. /// If someone was sending data, which of the sender or receiver continues next depends on <see cref="Preference"/>. /// </summary> /// <returns>Awaitable data.</returns> public ChannelMicroThreadAwaiter <T> Receive() { if (senders.Count == 0) { var microThread = MicroThread.Current; if (microThread == null) { throw new Exception("Cannot receive out of micro-thread context."); } var waitingMicroThread = ChannelMicroThreadAwaiter <T> .New(microThread); receivers.Enqueue(waitingMicroThread); return(waitingMicroThread); } var sender = senders.Dequeue(); if (Preference == ChannelPreference.PreferReceiver) { sender.MicroThread.ScheduleContinuation(ScheduleMode.Last, sender.Continuation); } else if (Preference == ChannelPreference.PreferSender) { sender.MicroThread.ScheduleContinuation(ScheduleMode.First, sender.Continuation); throw new NotImplementedException(); //await Scheduler.Yield(); } sender.IsCompleted = true; return(sender); }
/// <summary> /// Sends a value over the channel. If no other <see cref="MicroThread"/> is waiting for data, the sender will be blocked. /// If someone was waiting for data, which of the sender or receiver continues next depends on <see cref="Preference"/>. /// </summary> /// <param name="data">The data.</param> /// <returns>Awaitable data.</returns> public ChannelMicroThreadAwaiter <T> Send(T data) { if (receivers.Count == 0) { // Nobody receiving, let's wait until something comes up var microThread = MicroThread.Current; var waitingMicroThread = ChannelMicroThreadAwaiter <T> .New(microThread); waitingMicroThread.Result = data; senders.Enqueue(waitingMicroThread); return(waitingMicroThread); } var receiver = receivers.Dequeue(); receiver.Result = data; if (Preference == ChannelPreference.PreferSender) { receiver.MicroThread.ScheduleContinuation(ScheduleMode.Last, receiver.Continuation); } else if (Preference == ChannelPreference.PreferReceiver) { receiver.MicroThread.ScheduleContinuation(ScheduleMode.First, receiver.Continuation); throw new NotImplementedException(); //await Scheduler.Yield(); } receiver.IsCompleted = true; return(receiver); }