private async Task <T> CreateListenerTask <T>( Func <CancellationToken, Task <T> > producer, Channel <T> channel, Func <T, CancellationToken, Task <bool> > consumer, CancellationToken cancellationToken) { using var cts = new CancellationTokenSource(); using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken); var producerToChannelTask = ProducerConsumer.CreateAsync( producer, async(i, c) => { await channel.Writer.WriteAsync(i, c); return(true); }, linkedCts.Token, true); var channelToConsumerTask = ProducerConsumer.CreateAsync( (c) => channel.Reader.ReadAsync(c).AsTask(), consumer, linkedCts.Token, true); await Task.WhenAny(producerToChannelTask, channelToConsumerTask); // Cancel and awaits the both tasks again cts.Cancel(); var items = await Task.WhenAll(producerToChannelTask, channelToConsumerTask); return(items.FirstOrDefault(i => i != null)); }
public async Task StartAsync(CancellationToken cancellationToken = default(CancellationToken)) { await ListenerSemaphore.WaitAsync(cancellationToken); await _transportListener.StartAsync(); #pragma warning disable 4014 ProducerConsumer.CreateAsync( c => _transportListener.AcceptTransportAsync(c), async t => { await t.OpenAsync(null, _cts.Token); var serverChannel = new ServerChannel( Guid.NewGuid().ToString(), new Node("postmaster", "msging.net", "instance"), t, TimeSpan.FromSeconds(60), autoReplyPings: true); var clientNode = new Node("client", "msging.net", "instance"); await serverChannel.EstablishSessionAsync( new[] { SessionCompression.None }, new[] { SessionEncryption.None }, new[] { AuthenticationScheme.Guest, AuthenticationScheme.Key, AuthenticationScheme.Plain, AuthenticationScheme.Transport, }, (n, a) => new AuthenticationResult(null, clientNode).AsCompletedTask(), _cts.Token); var channelListener = new ChannelListener( m => TaskUtil.TrueCompletedTask, n => TaskUtil.TrueCompletedTask, async c => { if (c.Status == CommandStatus.Pending) { await serverChannel.SendCommandAsync( new Command(c.Id) { Status = CommandStatus.Success, Method = c.Method }, _cts.Token); } return(true); }); channelListener.Start(serverChannel); return(true); }, _cts.Token); }
private Task <T> CreateListenerTask <T>(Func <CancellationToken, Task <T> > producer, Func <T, CancellationToken, Task <bool> > consumer) { return(ProducerConsumer.CreateAsync( producer, consumer, _cts.Token, true)); }
private async Task <T> CreateListenerTask <T>(Func <CancellationToken, Task <T> > producer, Func <T, Task <bool> > consumer) { try { return(await ProducerConsumer.CreateAsync( producer, consumer, _cts.Token).ConfigureAwait(false)); } catch (OperationCanceledException) when(_cts.IsCancellationRequested) { return(default(T)); } }
public async Task StartAsync(CancellationToken cancellationToken = default(CancellationToken)) { await ListenerSemaphore.WaitAsync(cancellationToken); await _transportListener.StartAsync(); ProducerConsumer.CreateAsync( c => _transportListener.AcceptTransportAsync(c), async(transport, _) => { await transport.OpenAsync(null, _cts.Token); var serverChannel = new ServerChannel( Guid.NewGuid().ToString(), new Node("postmaster", "msging.net", "instance"), transport, TimeSpan.FromSeconds(60), autoReplyPings: true); await serverChannel.EstablishSessionAsync( new[] { SessionCompression.None }, new[] { SessionEncryption.None }, new[] { AuthenticationScheme.Guest, AuthenticationScheme.Key, AuthenticationScheme.Plain, AuthenticationScheme.Transport, AuthenticationScheme.External }, (n, a, _) => { Authentications.Enqueue(a); return(new AuthenticationResult(DomainRole.RootAuthority, a).AsCompletedTask()); }, (n, s, c) => { return(n.AsCompletedTask()); }, _cts.Token); var channelListener = new ChannelListener( m => { Messages.Enqueue(m); return(TaskUtil.TrueCompletedTask); }, n => { Notifications.Enqueue(n); return(TaskUtil.TrueCompletedTask); }, async c => { Commands.Enqueue(c); if (c.Status == CommandStatus.Pending) { await serverChannel.SendCommandAsync( new Command(c.Id) { Status = CommandStatus.Success, Method = c.Method }, _cts.Token); } return(true); }); channelListener.Start(serverChannel); Channels.Enqueue(serverChannel); return(true); }, _cts.Token); }