C# の例(9)
Channel を使ったバージョンは以下のようになります。
NumbersGenerator クラスの GenerateDecimal メソッドは以下のようになります。
public IteratorChannelImpl<int> GenerateDecimal() { bool SetToChannel(Channel<int> ch, int n) { async Task<bool> SetToChannel_a(Channel<int> ch, int n) { if (!await ch.Writer.WaitToWriteAsync().ConfigureAwait(false)) { return false; } if (!ch.Writer.TryWrite(n)) { return false; } return true; } return SetToChannel_a(ch, n).Result; } async Task serv(Channel<int> ch_get) { LongDecimal number = new LongDecimal(); LongDecimal square_difference = new LongDecimal(3); Numbers nums = new Numbers(number, square_difference, 0); for (; ; ) { int dd = nums.GetNextDecimalDigit(); if (!SetToChannel(ch_get, dd)) { break; } } } Channel<int> ch_get = Channel.CreateBounded<int>(1); Task.Run(() => serv(ch_get)); return new IteratorChannelImpl<int>(ch_get); }
NumbersServer クラスの GenerateDecimalServerメソッドは以下のようになります。
public IteratorChannelIOImpl<Numbers> GenerateDecimalServer() { Numbers numbers = new Numbers(new LongDecimal(), new LongDecimal(), 0); bool GetFromChannel(Channel<Numbers> ch) { async Task<bool> GetFromChannel_a(Channel<Numbers> ch) { if (!await ch.Reader.WaitToReadAsync().ConfigureAwait(false)) { return false; } if (!ch.Reader.TryRead(out numbers)) { return false; } return true; } return GetFromChannel_a(ch).Result; } bool SetToChannel(Channel<Numbers> ch, Numbers n) { async Task<bool> SetToChannel_a(Channel<Numbers> ch, Numbers n) { if (!await ch.Writer.WaitToWriteAsync().ConfigureAwait(false)) { return false; } if (!ch.Writer.TryWrite(n)) { return false; } return true; } return SetToChannel_a(ch, n).Result; } async Task serv(Channel<Numbers> ch_get, Channel<Numbers> ch_set) { LongDecimal number = new LongDecimal(); LongDecimal square_difference = new LongDecimal(3); Numbers current_numbers = new Numbers(number, square_difference, 0); for (; ; ) { if (!SetToChannel(ch_get, current_numbers)) { break; } if (!GetFromChannel(ch_get)) { break; } current_numbers = numbers; } } Channel<Numbers> ch_get = Channel.CreateBounded<Numbers>(1); Channel<Numbers> ch_set = Channel.CreateBounded<Numbers>(1); Task.Run(() => serv(ch_get, ch_set)); return new IteratorChannelIOImpl<Numbers>(ch_get, ch_set); }