コード例 #1
0
        public static Task <ConsumeContext <T> > SubscribeHandler <T>(this IBus bus, TimeSpan?timeout = null, CancellationToken cancelToken = default)
            where T : class
        {
            if (bus == null)
            {
                throw new ArgumentNullException(nameof(bus));
            }

            if (timeout.HasValue && timeout < Timeout.InfiniteTimeSpan)
            {
                throw new ArgumentOutOfRangeException(nameof(timeout));
            }

            ConnectHandle handler = null;

            var cts            = CancellationTokenSource.CreateLinkedTokenSource(cancelToken);
            var lnkCancelToken = cts.Token;

            var tcs = new TaskCompletionSource <ConsumeContext <T> >();

            if (timeout.HasValue && timeout.Value != Timeout.InfiniteTimeSpan)
            {
                cts.CancelAfter((new TimeSpan[] { timeout.Value, TimeSpan.FromMilliseconds(1000) }).Max());
            }

            handler = bus.ConnectHandler <T>(context =>
            {
                cts.Dispose();
                if (tcs.TrySetResult(context))
                {
                    handler.Disconnect();
                }
                return(Task.CompletedTask);
            });

            if (!tcs.Task.IsCompleted)
            {
                lnkCancelToken.Register(() =>
                {
                    cts.Dispose();
                    if (tcs.TrySetCanceled())
                    {
                        handler.Disconnect();
                    }
                });
            }

            return(tcs.Task);
        }