コード例 #1
0
        public Task ExecuteAsync(Command <M> command)
        {
            var response = new WriteOnceBlock <object>(b => b);

            _journaler.Post(new CommandRequest(command, response));
            return(response.ReceiveAsync());
        }
コード例 #2
0
        public void AsyncReceiveTestCanceled()
        {
            var src = new CancellationTokenSource();

            var block = new WriteOnceBlock <int> (null);
            var task  = block.ReceiveAsync(src.Token);

            Task.Factory.StartNew(() => { Thread.Sleep(800); block.Post(42); });
            Thread.Sleep(50);
            src.Cancel();

            AggregateException ex = null;

            try {
                task.Wait();
            } catch (AggregateException e) {
                ex = e;
            }

            Assert.IsNotNull(ex);
            Assert.IsNotNull(ex.InnerException);
            Assert.IsInstanceOfType(typeof(OperationCanceledException), ex.InnerException);
            Assert.IsTrue(task.IsCompleted);
            Assert.AreEqual(TaskStatus.Canceled, task.Status);
        }
コード例 #3
0
        public async Task <R> ExecuteAsync <R>(Query <M, R> query)
        {
            var response = new WriteOnceBlock <object>(r => r);

            _executionPipeline.Post(new QueryRequest(query, response));
            return((R)await response.ReceiveAsync());
        }
コード例 #4
0
        public async Task <DiscoveredServerInfo> DiscoverReturnFirstAsync()
        {
            Task discoverAllTask = DiscoverAllAsync();
            Task <DiscoveredServerInfo> firstTask = m_wbFirstResult.ReceiveAsync();
            Task res = await Task.WhenAny(discoverAllTask, firstTask);

            try
            {
                if (res == firstTask)
                {
                    return(await firstTask);
                }
                else
                {
                    await discoverAllTask;
                    if (FoundServer.Count > 0)
                    {
                        return(FoundServer[0]);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
            catch (OperationCanceledException)
            {
                return(null);
            }
        }
コード例 #5
0
        public async Task <R> ExecuteAsync <R>(Command <M, R> command)
        {
            var response = new WriteOnceBlock <object>(r => r);

            _journaler.Post(new CommandRequest(command, response));
            return((R)await response.ReceiveAsync());
        }
コード例 #6
0
 public async Task AllDisposeAsync()
 {
     //before dispose requestStream need to
     //wait 60 second to receive 'completed' from client side.
     await Task.WhenAny(Task.Delay(1000 * 60),
                        _end.ReceiveAsync());
 }
コード例 #7
0
ファイル: Program.cs プロジェクト: lsfera/Tesseract
        // This demonstrates the behavior of the WriteOnceBlock as it's easy to observe.
        //
        // Preface: I hate the name of this block. It's misleading. This should have been
        // called CloneBlock or CacheBlock. WriteOnceBlock sounds like you use the block once
        // and it then self-destructs.

        // How it works is simple, it will accept one published message and reject all other messages
        // coming to it. It will then take the first message and clone it and send it on every request
        // downstream.
        private static async Task WriteBlockBehaviorDemoAsync()
        {
            Console.WriteLine("WriteOneBlockDemo has started!");
            var block = new WriteOnceBlock <string>(input => input); // needs a clone function

            for (int i = 0; i < 5; i++)
            {
                if (block.Post(ProduceTimeData()))
                {
                    Console.WriteLine($"Message {i} was accepted");
                }
                else
                {
                    Console.WriteLine($"Message {i} was rejected");
                }
            }

            // Notice the count is much higher than input count and that I am not
            // waiting on it to signal no more data is coming, as it always has data.
            for (int i = 0; i < 15; i++)
            {
                var output = await block.ReceiveAsync().ConfigureAwait(false);

                Console.WriteLine($"ReceivedMessage {i}: {output}");
            }

            block.Complete();
            await block.Completion.ConfigureAwait(false);

            Console.WriteLine("Finished!");
            Console.ReadKey();
        }
コード例 #8
0
        public async Task <ServiceOnceCallParam> GetServiceOnceCallParamAsync()
        {
            var requestBody = await _cmdReq.ReceiveAsync();

            var ocp = requestBody.ToObject <OnceCallParam>();

            //stream
            ReadStream?rs;

            if (ocp.HasStream)
            {
                if (ocp.PostStream != null)
                {
                    rs = new ProxyStream(new MemoryStream(ocp.PostStream));
                }
                else
                {
                    rs = new ProxyStream(_streamPipe.InputStream, ocp.StreamLength, true);
                }
            }
            else
            {
                rs = null;
            }

            return(new ServiceOnceCallParam(ocp.Action, ocp.PureArgs, ocp.StreamLength, rs, ocp.Header));
        }
コード例 #9
0
ファイル: AsyncTaskBase.cs プロジェクト: bardway/mingriland
        public async Task <TResult> InvokeAsync()
        {
            if (_invoked)
            {
                throw new InvalidOperationException("Already invoded.");
            }

            _invoked = true;

            try
            {
                var waitTask = _cancelToken != null?_wobResult.ReceiveAsync(_cancelToken.Value) : _wobResult.ReceiveAsync();

                Invoke();

                var resultTask = await Task.WhenAny(waitTask, Task.Delay(_timeOutMs));

                if (resultTask == waitTask)
                {
                    return(waitTask.Result);
                }

                throw new TimeoutException();
            }
            catch (Exception ex)
            {
                Exception(ex);
                return(default(TResult));
            }
            finally
            {
                Dispose();
            }
        }
コード例 #10
0
ファイル: UserProxy.cs プロジェクト: mattolenik/winston
 public async Task<string> AskAsync(Question question)
 {
     var b = new WriteOnceBlock<string>(s => s);
     question.answerBlock = b;
     // TODO: handle if buffer refuses message? If task.Result is false
     var task = await buf.SendAsync(question);
     return await b.ReceiveAsync();
 }
コード例 #11
0
ファイル: NmsProtocol.cs プロジェクト: sarakusha/Nibus.NET
        /// <summary>
        /// Отправляет NMS-сообщение <paramref name="query"/> и ожидает ответа.
        /// Асинхронная операция.
        /// </summary>
        /// <typeparam name="TMessage">Тип сообщения, потомок NmsMessage.</typeparam>
        /// <param name="query">Сообщение-запрос.</param>
        /// <param name="options">Параметры асинхронной операции.</param>
        /// <returns>
        ///  <see cref="Task{TResult}"/> асинхронная операция - ответное сообщение.
        /// </returns>
        /// <exception cref="AggregateException">Призошла ошибка в асинхронном коде. См. <see cref="Exception.InnerException"/></exception>
        /// <exception cref="TimeoutException">Ошибка по таймауту.</exception>
        /// <exception cref="TaskCanceledException">Операция прервана пользователем.</exception>
        /// <exception cref="NibusResponseException">Ошибка NiBUS.</exception>
        public async Task <TMessage> WaitForNmsResponseAsync <TMessage>(TMessage query, NibusOptions options = null)
            where TMessage : NmsMessage
        {
            //Contract.Requires(!IsDisposed);
            //Contract.Requires(
            //    query.Datagram.Destanation.Type == AddressType.Hardware
            //    || query.Datagram.Destanation.Type == AddressType.Net);

            options = GetDefaultOrClone(options);

            // Последнее сообщение в BroadcastBlock всегда остается! Незабываем его фильтровать.
            NmsMessage lastMessage;

            IncomingMessages.TryReceive(null, out lastMessage);

            var wob = new WriteOnceBlock <NmsMessage>(m => m);

            using (IncomingMessages.LinkTo(
                       wob,
                       m => !ReferenceEquals(lastMessage, m) && m.IsResponse && m.ServiceType == query.ServiceType &&
                       (query.Id == 0 || m.Id == query.Id) && (query.Datagram.Destanation == Address.Empty || m.Datagram.Source == query.Datagram.Destanation)))
            {
                for (var i = 0; i < options.Attempts; i++)
                {
                    await OutgoingMessages.SendAsync(query);

                    try
                    {
                        var response =
                            (TMessage)await wob.ReceiveAsync(options.Timeout, options.Token).ConfigureAwait(false);

                        if (response.ErrorCode != 0)
                        {
                            throw new NibusResponseException(response.ErrorCode);
                        }

                        return(response);
                    }
                    catch (TimeoutException)
                    {
                        Logger.Debug("Timeout {0}", i + 1);
                        if (i < options.Attempts - 1)
                        {
                            continue;
                        }
                        throw;
                    }
                }
            }

            // Эта точка недостижима при attempts > 0!
            throw new InvalidOperationException();
        }
コード例 #12
0
        public void AsyncReceiveTest()
        {
            int result = -1;
            var mre    = new ManualResetEventSlim(false);

            var block = new WriteOnceBlock <int> (null);

            block.ReceiveAsync().ContinueWith(i => { result = i.Result; mre.Set(); });
            Task.Factory.StartNew(() => { Thread.Sleep(600); block.Post(42); });
            mre.Wait();

            Assert.AreEqual(42, result);
        }
コード例 #13
0
        public async Task TestReceiveThenPost()
        {
            var wob     = new WriteOnceBlock <int>(null);
            var ignored = Task.Run(() => wob.Post(42));

            Assert.Equal(expected: 42, actual: wob.Receive()); // this should always pass, but due to race we may not test what we're hoping to
            await wob.Completion;

            wob = new WriteOnceBlock <int>(null);
            Task <int> t = wob.ReceiveAsync();

            Assert.False(t.IsCompleted);
            wob.Post(16);
            Assert.Equal(expected: 16, actual: await t);
        }
コード例 #14
0
        public async Task <Match> FindMatchAsync(UserBoard player)
        {
            if (!_players.TryAdd(player.Username, player))
            {
                return(null);
            }

            var block = new WriteOnceBlock <Match>(null);

            if (!_blocks.TryAdd(player.Username, block))
            {
                _players.Remove(player.Username);
                return(null);
            }

            LookForMatches(player, block);
            return(await block.ReceiveAsync());
        }
コード例 #15
0
ファイル: NmsProtocol.cs プロジェクト: sarakusha/Nibus.NET
        private async Task <NmsRead> GetNmsReadResponseAsync(
            NmsMessage lastMessage, Address target, int id, NibusOptions options)
        {
            var wob = new WriteOnceBlock <NmsMessage>(m => m);

            using (IncomingMessages.LinkTo(
                       wob,
                       m => !ReferenceEquals(lastMessage, m) && m.IsResponse && m.ServiceType == NmsServiceType.Read &&
                       m.Id == id && (target == Address.Empty || m.Datagram.Source == target)))
            {
                var response = (NmsRead)await wob.ReceiveAsync(options.Timeout, options.Token).ConfigureAwait(false);

                if (response.ErrorCode != 0)
                {
                    throw new NibusResponseException(response.ErrorCode);
                }

                return(response);
            }
        }
コード例 #16
0
        public async Task TestPostThenReceive()
        {
            var wob = new WriteOnceBlock <int>(i => i);

            for (int i = 10; i < 15; i++)
            {
                bool posted = wob.Post(i);
                Assert.Equal(expected: i == 10, actual: posted);
            }
            int item;

            Assert.True(wob.TryReceive(out item));
            Assert.Equal(expected: 10, actual: item);
            await wob.Completion;

            wob = new WriteOnceBlock <int>(null);
            wob.Post(42);
            Task <int> t = wob.ReceiveAsync();

            Assert.True(t.IsCompleted);
            Assert.Equal(expected: 42, actual: t.Result);
            await wob.Completion;
        }
コード例 #17
0
        public async Task TestCloning()
        {
            // Test cloning when a clone function is provided
            {
                int data = 42;
                var wob  = new WriteOnceBlock <int>(x => - x);
                Assert.True(wob.Post(data));

                Assert.False(wob.Post(data + 1));

                for (int i = 0; i < 3; i++)
                {
                    int item;
                    Assert.True(wob.TryReceive(out item));
                    Assert.Equal(expected: -data, actual: item);

                    Assert.Equal(expected: -data, actual: wob.Receive());

                    Assert.Equal(expected: -data, actual: await wob.ReceiveAsync());

                    IList <int> items;
                    Assert.True(((IReceivableSourceBlock <int>)wob).TryReceiveAll(out items));
                    Assert.Equal(expected: items.Count, actual: 1);
                    Assert.Equal(expected: -data, actual: items[0]);
                }

                int result = 0;
                var target = new ActionBlock <int>(i => {
                    Assert.Equal(expected: 0, actual: result);
                    result = i;
                    Assert.Equal(expected: -data, actual: i);
                });
                wob.LinkTo(target, new DataflowLinkOptions {
                    PropagateCompletion = true
                });
                await target.Completion;
            }

            // Test successful processing when no clone function exists
            {
                var data = new object();
                var wob  = new WriteOnceBlock <object>(null);
                Assert.True(wob.Post(data));

                Assert.False(wob.Post(new object()));

                object result;
                for (int i = 0; i < 3; i++)
                {
                    Assert.True(wob.TryReceive(out result));
                    Assert.Equal(expected: data, actual: result);

                    Assert.Equal(expected: data, actual: wob.Receive());
                    Assert.Equal(expected: data, actual: await wob.ReceiveAsync());

                    IList <object> items;
                    Assert.True(((IReceivableSourceBlock <object>)wob).TryReceiveAll(out items));
                    Assert.Equal(expected: 1, actual: items.Count);
                    Assert.Equal(expected: data, actual: items[0]);
                }

                result = null;
                var target = new ActionBlock <object>(o => {
                    Assert.Null(result);
                    result = o;
                    Assert.Equal(expected: data, actual: o);
                });
                wob.LinkTo(target, new DataflowLinkOptions {
                    PropagateCompletion = true
                });
                await target.Completion;
            }
        }
コード例 #18
0
        public async Task TestReceiveThenPost()
        {
            var wob = new WriteOnceBlock<int>(null);
            var ignored = Task.Run(() => wob.Post(42));
            Assert.Equal(expected: 42, actual: wob.Receive()); // this should always pass, but due to race we may not test what we're hoping to
            await wob.Completion;

            wob = new WriteOnceBlock<int>(null);
            Task<int> t = wob.ReceiveAsync();
            Assert.False(t.IsCompleted);
            wob.Post(16);
            Assert.Equal(expected: 16, actual: await t);
        }
コード例 #19
0
        public async Task TestCloning()
        {
            // Test cloning when a clone function is provided
            {
                int data = 42;
                var wob = new WriteOnceBlock<int>(x => -x);
                Assert.True(wob.Post(data));

                Assert.False(wob.Post(data + 1));

                for (int i = 0; i < 3; i++)
                {
                    int item;
                    Assert.True(wob.TryReceive(out item));
                    Assert.Equal(expected: -data, actual: item);

                    Assert.Equal(expected: -data, actual: wob.Receive());

                    Assert.Equal(expected: -data, actual: await wob.ReceiveAsync());

                    IList<int> items;
                    Assert.True(((IReceivableSourceBlock<int>)wob).TryReceiveAll(out items));
                    Assert.Equal(expected: items.Count, actual: 1);
                    Assert.Equal(expected: -data, actual: items[0]);
                }

                int result = 0;
                var target = new ActionBlock<int>(i => {
                    Assert.Equal(expected: 0, actual: result);
                    result = i;
                    Assert.Equal(expected: -data, actual: i);
                });
                wob.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true });
                await target.Completion;
            }

            // Test successful processing when no clone function exists
            {
                var data = new object();
                var wob = new WriteOnceBlock<object>(null);
                Assert.True(wob.Post(data));

                Assert.False(wob.Post(new object()));

                object result;
                for (int i = 0; i < 3; i++)
                {
                    Assert.True(wob.TryReceive(out result));
                    Assert.Equal(expected: data, actual: result);

                    Assert.Equal(expected: data, actual: wob.Receive());
                    Assert.Equal(expected: data, actual: await wob.ReceiveAsync());

                    IList<object> items;
                    Assert.True(((IReceivableSourceBlock<object>)wob).TryReceiveAll(out items));
                    Assert.Equal(expected: 1, actual: items.Count);
                    Assert.Equal(expected: data, actual: items[0]);
                }

                result = null;
                var target = new ActionBlock<object>(o => {
                    Assert.Null(result);
                    result = o;
                    Assert.Equal(expected: data, actual: o);
                });
                wob.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true });
                await target.Completion;
            }
        }
コード例 #20
0
        /// <summary>
        /// Connect to a target on first of bound proxies, or use ping based dynamic lookup
        /// </summary>
        /// <param name="address"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public override async Task ConnectAsync(SocketAddress address, CancellationToken ct)
        {
            Info.Address = address;
            if (Info.Address.Family == AddressFamily.Bound)
            {
                // Unwrap proxy and connect address.  If not bound, use local address to bind to.
                if (_boundEndpoint == null)
                {
                    _boundEndpoint = address;
                    // Unwrap bound address
                    while (_boundEndpoint.Family == AddressFamily.Bound)
                    {
                        _boundEndpoint = ((BoundSocketAddress)_boundEndpoint).LocalAddress;
                    }
                }
                Info.Address = ((BoundSocketAddress)Info.Address).RemoteAddress;
            }

            //
            // Get the named host from the registry if it exists - there should only be one...
            // This is the host we shall connect to.  It can contain proxies to use as well.
            //
            var hostList = await Provider.NameService.LookupAsync(
                Info.Address.ToString(), NameRecordType.Host, ct).ConfigureAwait(false);

            Host = hostList.FirstOrDefault();
            if (Host == null)
            {
                // If there is no host in the registry, create a fake host record for this address
                Host = new NameRecord(NameRecordType.Host, Info.Address.ToString());
            }
            else
            {
                if (!Host.Name.Equals(Info.Address.ToString(), StringComparison.CurrentCultureIgnoreCase))
                {
                    // Translate the address to host address
                    Info.Address = new ProxySocketAddress(Host.Name);
                }
            }

            // Commit all options that were set until now into info
            Info.Options.UnionWith(_optionCache.Select(p => Property <ulong> .Create(
                                                           (uint)p.Key, p.Value)));

            //
            // Create tpl network for connect - prioritize input above errored attempts using
            // prioritized scheduling queue.
            //
            var retries = new CancellationTokenSource();

            ct.Register(() => retries.Cancel());
            var errors = new TransformBlock <DataflowMessage <INameRecord>, DataflowMessage <INameRecord> >(
                async(error) => {
                if (error.FaultCount > 0)
                {
                    Host.RemoveReference(error.Arg.Address);
                    await Provider.NameService.AddOrUpdateAsync(Host, retries.Token).ConfigureAwait(false);
                    ProxyEventSource.Log.LinkFailure(this, error.Arg, Host, error.LastFault);
                }
                await Task.Delay((error.FaultCount + 1) * _throttleDelayMs, retries.Token).ConfigureAwait(false);
                return(error);
            },
                new ExecutionDataflowBlockOptions {
                NameFormat             = "Error (Connect) Id={1}",
                MaxDegreeOfParallelism = 2, // 2 parallel retries
                CancellationToken      = retries.Token
            });

            var linkAdapter = DataflowMessage <INameRecord> .CreateAdapter(
                new ExecutionDataflowBlockOptions {
                NameFormat                = "Adapt (Connect) Id={1}",
                CancellationToken         = ct,
                MaxDegreeOfParallelism    = DataflowBlockOptions.Unbounded,
                MaxMessagesPerTask        = DataflowBlockOptions.Unbounded,
                SingleProducerConstrained = true,
                EnsureOrdered             = false
            });

            var linkQuery = Provider.NameService.Read(
                new ExecutionDataflowBlockOptions {
                NameFormat        = "Query (Connect) Id={1}",
                CancellationToken = ct,
                EnsureOrdered     = true
            });

            var pinger = CreatePingBlock(errors, Info.Address,
                                         new ExecutionDataflowBlockOptions {
                NameFormat             = "Ping (Connect) Id={1}",
                CancellationToken      = ct,
                MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded,
                MaxMessagesPerTask     = 1,
                EnsureOrdered          = false
            });

            var linker = CreateLinkBlock(errors,
                                         new ExecutionDataflowBlockOptions {
                NameFormat             = "Link (Connect) Id={1}",
                CancellationToken      = ct,
                MaxDegreeOfParallelism = 1, // Ensure one link is created at a time.
                MaxMessagesPerTask     = DataflowBlockOptions.Unbounded,
                EnsureOrdered          = false
            });

            var connection = new WriteOnceBlock <IProxyLink>(l => l,
                                                             new DataflowBlockOptions {
                NameFormat         = "Final (Connect) Id={1}",
                MaxMessagesPerTask = 1, // Auto complete when link is created
                EnsureOrdered      = false
            });

            linkQuery.ConnectTo(linkAdapter);
            linkAdapter.ConnectTo(linker);
            errors.ConnectTo(pinger);
            pinger.ConnectTo(linker);
            linker.ConnectTo(connection);

            //
            // Now connect by starting the connection pipeline from query source...
            //
            if (_boundEndpoint != null)
            {
                //
                // User asked for specific set of proxies. Try linking with each
                // until we have a successful link.
                //
                await linkQuery.SendAsync(r => r.Matches(_boundEndpoint,
                                                         NameRecordType.Proxy), ct).ConfigureAwait(false);
            }
            else
            {
                //
                // Consider all endpoints - if the host has a candidate list
                // use this list to directly link, and then ping remaining with
                // a throttle.  Otherwise do a full ping.
                //
                var pingAdapter = DataflowMessage <INameRecord> .CreateAdapter(
                    new ExecutionDataflowBlockOptions {
                    NameFormat                = "Any (Connect) Id={1}",
                    CancellationToken         = ct,
                    MaxDegreeOfParallelism    = DataflowBlockOptions.Unbounded,
                    MaxMessagesPerTask        = DataflowBlockOptions.Unbounded,
                    SingleProducerConstrained = true,
                    EnsureOrdered             = false
                });

                var remaining = Provider.NameService.Read(
                    new ExecutionDataflowBlockOptions {
                    NameFormat        = "Remaining (Connect) Id={1}",
                    CancellationToken = ct,
                    EnsureOrdered     = true
                });

                remaining.ConnectTo(pingAdapter);

                if (Host.References.Any())
                {
                    // Delay ping through errors path to give references time to link...
                    pingAdapter.ConnectTo(errors);
                    await linkQuery.SendAsync(r => r.Matches(Host.References,
                                                             NameRecordType.Proxy), ct).ConfigureAwait(false);
                }
                else
                {
                    // Send directly to ping
                    pingAdapter.ConnectTo(pinger);
                }

                await remaining.SendAsync(r => r.IsProxyForHost(Info.Address), ct)
                .ConfigureAwait(false);
            }

            // Wait until a connected link is received.  Then cancel the remainder of the pipeline.
            try {
                _link = await connection.ReceiveAsync(ct);

                connection.Complete();
                retries.Cancel();

                Host.AddReference(_link.Proxy.Address);
                Host.LastActivity = _link.Proxy.LastActivity = DateTime.Now;
                await Provider.NameService.AddOrUpdateAsync(_link.Proxy, ct).ConfigureAwait(false);
            }
            catch (Exception e) {
                throw SocketException.Create("Failed to connect", e);
            }
            finally {
                await Provider.NameService.AddOrUpdateAsync(Host, ct).ConfigureAwait(false);
            }
        }
コード例 #21
0
        public async Task TestPostThenReceive()
        {
            var wob = new WriteOnceBlock<int>(i => i);
            for (int i = 10; i < 15; i++)
            {
                bool posted = wob.Post(i);
                Assert.Equal(expected: i == 10, actual: posted);
            }
            int item;
            Assert.True(wob.TryReceive(out item));
            Assert.Equal(expected: 10, actual: item);
            await wob.Completion;

            wob = new WriteOnceBlock<int>(null);
            wob.Post(42);
            Task<int> t = wob.ReceiveAsync();
            Assert.True(t.IsCompleted);
            Assert.Equal(expected: 42, actual: t.Result);
            await wob.Completion;
        }
コード例 #22
0
ファイル: DataflowBlockTest.cs プロジェクト: Profit0004/mono
		public void AsyncReceiveTest ()
		{
			int result = -1;
			var mre = new ManualResetEventSlim (false);

			var block = new WriteOnceBlock<int> (null);
			block.ReceiveAsync ().ContinueWith (i =>
			{
				result = i.Result;
				mre.Set ();
			});
			Task.Factory.StartNew (() =>
			{
				Thread.Sleep (100);
				block.Post (42);
			});
			Assert.IsTrue (mre.Wait (1000));

			Assert.AreEqual (42, result);
		}
コード例 #23
0
ファイル: DataflowBlockTest.cs プロジェクト: Profit0004/mono
		public void AsyncReceiveTestCanceled ()
		{
			var src = new CancellationTokenSource ();

			var block = new WriteOnceBlock<int> (null);
			var task = block.ReceiveAsync (src.Token);
			Task.Factory.StartNew (() =>
			{
				Thread.Sleep (800);
				block.Post (42);
			});
			Thread.Sleep (50);
			src.Cancel ();

			AggregateException ex = null;

			try {
				task.Wait ();
			} catch (AggregateException e) {
				ex = e;
			}

			Assert.IsNotNull (ex);
			Assert.IsNotNull (ex.InnerException);
			Assert.IsInstanceOfType (typeof(OperationCanceledException),
				ex.InnerException);
			Assert.IsTrue (task.IsCompleted);
			Assert.AreEqual (TaskStatus.Canceled, task.Status);
		}
コード例 #24
0
    public async Task TestWriteOnceBlock()
    {
        var writeOnceBlockTest = new WriteOnceBlock <int>(i => i);
        var queueBlockTest     = new BufferBlock <string>();
        var transformBlockTest = new TransformBlock <string, Tuple <int, string> >(async str => Tuple.Create(await writeOnceBlockTest.ReceiveAsync(), str));
        var actionBlockTest    = new ActionBlock <Tuple <int, string> >(tuple => Console.WriteLine($"I received int {tuple.Item1} and string {tuple.Item2}."));

        queueBlockTest.LinkTo(transformBlockTest, new DataflowLinkOptions {
            PropagateCompletion = true
        });
        transformBlockTest.LinkTo(actionBlockTest, new DataflowLinkOptions {
            PropagateCompletion = true
        });
        writeOnceBlockTest.Post(3);
        queueBlockTest.Post("String1");
        queueBlockTest.Post("String2");
        writeOnceBlockTest.Post(4);
        writeOnceBlockTest.Post(5);
        queueBlockTest.Post("String3");
        queueBlockTest.Post("String4");
        queueBlockTest.Complete();
        await actionBlockTest.Completion;
    }