private async Task Run() { var sw = new SpinWait(); while (!_input.All(bc => bc.IsCompleted) && !_token.IsCancellationRequested) { var i = BlockingCollection <TInput> .TryTakeFromAny(_input, out var receivedItem, 50, _token); if (i >= 0) { TOutput outputItem = _processor != null?_processor(receivedItem) : await _processoTask(receivedItem); BlockingCollection <TOutput> .AddToAny(Output, outputItem); sw.SpinOnce(); } else { Thread.SpinWait(1000); } } if (Output != null) { foreach (var bc in Output) { bc.CompleteAdding(); } } }
public static bool ExternalCancel_AddToAny() { TestHarness.TestLog("* BlockingCollectionCancellationTests.ExternalCancel_AddToAny()"); bool passed = true; BlockingCollection <int> bc1 = new BlockingCollection <int>(1); BlockingCollection <int> bc2 = new BlockingCollection <int>(1); bc1.Add(1); //fill the bc. bc2.Add(1); //fill the bc. CancellationTokenSource cs = new CancellationTokenSource(); ThreadPool.QueueUserWorkItem( (obj) => { Thread.Sleep(100); cs.Cancel(); }); passed &= TestHarnessAssert.IsFalse(cs.IsCancellationRequested, "At this point the cancel should not have occurred."); passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown( () => BlockingCollection <int> .AddToAny(new [] { bc1, bc2 }, 1, cs.Token), cs.Token, "The operation should wake up via token cancellation."); return(passed); }
public static void ExternalCancel_AddToAny() { for (int test = 0; test < 3; test++) { BlockingCollection <int> bc1 = new BlockingCollection <int>(1); BlockingCollection <int> bc2 = new BlockingCollection <int>(1); bc1.Add(1); //fill the bc. bc2.Add(1); //fill the bc. // This may or may not cancel before {Try}AddToAny executes, but either way the test should pass. // A delay could be used to attempt to force the right timing, but not for an inner loop test. CancellationTokenSource cs = new CancellationTokenSource(); Task.Run(() => cs.Cancel()); Assert.Throws <OperationCanceledException>(() => { switch (test) { case 0: BlockingCollection <int> .AddToAny(new[] { bc1, bc2 }, 42, cs.Token); break; case 1: BlockingCollection <int> .TryAddToAny(new[] { bc1, bc2 }, 42, Timeout.Infinite, cs.Token); break; case 2: BlockingCollection <int> .TryAddToAny(new[] { bc1, bc2 }, 42, (int)TimeSpan.FromDays(1).TotalMilliseconds, cs.Token); break; } }); Assert.True(cs.IsCancellationRequested); } }
public void Run() { while (!Input.All(inputBC => inputBC.IsCompleted) && !_token.IsCancellationRequested) { TInput item; int i = BlockingCollection <TInput> .TryTakeFromAny(Input, out item, TIMEOUT, _token); if (i >= 0) { if (Output != null) { TOutput result = _processor(item); BlockingCollection <TOutput> .AddToAny(Output, result, _token); } else { _outputProcessor(item); } } } if (Output != null) { foreach (var outputBC in Output) { outputBC.CompleteAdding(); } } }
public static void UsingMultipleBlockingCollection() { BlockingCollection <string> bc1 = new BlockingCollection <string>(); BlockingCollection <string> bc2 = new BlockingCollection <string>(); BlockingCollection <string> bc3 = new BlockingCollection <string>(); BlockingCollection <string>[] bc1andbc2 = { bc1, bc2 }; BlockingCollection <string>[] bcAll = { bc1, bc2, bc3 }; CancellationTokenSource tokenSource = new CancellationTokenSource(); for (int i = 0; i < 5; i++) { Task.Factory.StartNew(() => { while (!tokenSource.IsCancellationRequested) { string message = String.Format("Message from task {0}", Task.CurrentId); BlockingCollection <string> .AddToAny(bc1andbc2, message, tokenSource.Token); tokenSource.Token.WaitHandle.WaitOne(1000); } }, tokenSource.Token); } for (int i = 0; i < 3; i++) { Task.Factory.StartNew(() => { while (!tokenSource.IsCancellationRequested) { string warning = String.Format("Warning from task {0}", Task.CurrentId); bc3.Add(warning, tokenSource.Token); tokenSource.Token.WaitHandle.WaitOne(500); } }, tokenSource.Token); } for (int i = 0; i < 2; i++) { Task consumer = Task.Factory.StartNew(() => { string item; while (!tokenSource.IsCancellationRequested) { int bcid = BlockingCollection <string> .TakeFromAny(bcAll, out item, tokenSource.Token); Console.WriteLine("From collection {0} : {1}", bcid, item); } }, tokenSource.Token); } Console.WriteLine("Press enter to cancel tasks"); Console.ReadLine(); tokenSource.Cancel(); EndofProgram(); }
public void Run() { WriteLine($"{Name} is runing!"); //确定是否对序列中的所有元素都满足条件 while (!_input.All(bc => bc.IsCompleted) && !_token.IsCancellationRequested) { TInput receivedItem; //尝试从任一指定的BlockingCollection实例中移除一个项。 //从其中一个集合中移除的项。 //等待的毫秒数,或为 System.Threading.Timeout.Infinite (-1),表示无限期等待。 //要观察的取消标记。 //从其中移除项的集合在 collections 数组中的索引;如果未能移除项,则为 -1。 int i = BlockingCollection <TInput> .TryTakeFromAny(_input, out receivedItem, 50, _token); //移除成功 if (i >= 0) { if (Output != null) { TOutput outputItem = _processor(receivedItem); BlockingCollection <TOutput> .AddToAny(Output, outputItem); WriteLine($"{Name} sent {outputItem} to next,on" + $"Thread id {CurrentThread.ManagedThreadId}"); Sleep(TimeSpan.FromMilliseconds(_rnd.Next(200))); } else { _outputProcessor(receivedItem); } } else { Sleep(TimeSpan.FromMilliseconds(50)); } } if (Output != null) { foreach (var bc in Output) { bc.CompleteAdding(); } } }
public static void ExternalCancel_Negative() { BlockingCollection <int> bc = new BlockingCollection <int>(); //empty collection. CancellationTokenSource cs = new CancellationTokenSource(); Task.Run(() => cs.Cancel()); int item; EnsureOperationCanceledExceptionThrown( () => bc.Take(cs.Token), cs.Token, "ExternalCancel_Take: The operation should wake up via token cancellation."); EnsureOperationCanceledExceptionThrown( () => bc.TryTake(out item, 100000, cs.Token), cs.Token, "ExternalCancel_TryTake: The operation should wake up via token cancellation."); EnsureOperationCanceledExceptionThrown( () => bc.Add(1, cs.Token), cs.Token, "ExternalCancel_Add: The operation should wake up via token cancellation."); EnsureOperationCanceledExceptionThrown( () => bc.TryAdd(1, 100000, cs.Token), // a long timeout. cs.Token, "ExternalCancel_TryAdd: The operation should wake up via token cancellation."); BlockingCollection <int> bc1 = new BlockingCollection <int>(1); BlockingCollection <int> bc2 = new BlockingCollection <int>(1); bc1.Add(1); //fill the bc. bc2.Add(1); //fill the bc. EnsureOperationCanceledExceptionThrown( () => BlockingCollection <int> .AddToAny(new[] { bc1, bc2 }, 1, cs.Token), cs.Token, "ExternalCancel_AddToAny: The operation should wake up via token cancellation."); EnsureOperationCanceledExceptionThrown( () => BlockingCollection <int> .TryAddToAny(new[] { bc1, bc2 }, 1, 10000, cs.Token), cs.Token, "ExternalCancel_AddToAny: The operation should wake up via token cancellation."); IEnumerable <int> enumerable = bc.GetConsumingEnumerable(cs.Token); EnsureOperationCanceledExceptionThrown( () => enumerable.GetEnumerator().MoveNext(), cs.Token, "ExternalCancel_GetConsumingEnumerable: The operation should wake up via token cancellation."); }
private static void UsingMultipleBlockingCollectionInstances() { var bc1 = new BlockingCollection <string>(); var bc2 = new BlockingCollection <string>(); var bc3 = new BlockingCollection <string>(); var bc1And2 = new [] { bc1, bc2 }; var bcAll = new [] { bc1, bc2, bc3 }; var tokenSource = new CancellationTokenSource(); for (int i = 0; i < 5; i++) { Task.Factory.StartNew(() => { while (!tokenSource.IsCancellationRequested) { var message = string.Format($"Message from task {Task.CurrentId}"); BlockingCollection <string> .AddToAny(bc1And2, message, tokenSource.Token); tokenSource.Token.WaitHandle.WaitOne(1000); } }, tokenSource.Token); } for (int j = 0; j < 3; j++) { Task.Factory.StartNew(() => { while (!tokenSource.IsCancellationRequested) { int bcId = BlockingCollection <string> .TakeFromAny(bcAll, out var item, tokenSource.Token); Console.WriteLine($"From collection {bcId}: {item}"); } }, tokenSource.Token); } Console.WriteLine("Press enter to cancel tasks..."); Console.ReadLine(); tokenSource.Cancel(); }
public void Run() { Console.WriteLine($"{Name} is run"); while (!_intput.All(bc => bc.IsCompleted) && !_token.IsCancellationRequested) { TInput receivedItem; int i = BlockingCollection <TInput> .TryTakeFromAny( _intput, out receivedItem, 50, _token); if (i >= 0) { if (Output != null) { TOutput outputItem = _processor(receivedItem); BlockingCollection <TOutput> .AddToAny(Output, outputItem); Console.WriteLine($"{Name} sent {outputItem} to next, on thread id {Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(TimeSpan.FromMilliseconds(_rnd.Next(200))); } else { _outputProcessor(receivedItem); } } else { Thread.Sleep(TimeSpan.FromMilliseconds(50)); } } if (Output != null) { foreach (var bc in Output) { bc.CompleteAdding(); } } }
public void Process() { Console.WriteLine($"{Name} is running"); while (!inputValues.All(bc => bc.IsCompleted) && !ct.IsCancellationRequested) { TInput inputItem; int i = BlockingCollection <TInput> .TryTakeFromAny(inputValues, out inputItem, 50, ct); if (i >= 0) { if (outputValues != null) { TOutput outputItem = processor(inputItem); BlockingCollection <TOutput> .AddToAny(outputValues, outputItem); Console.WriteLine($"{Name} sent {outputItem} to next"); } else { outputProcessor(inputItem); } } else { Console.WriteLine("Unable to retrieve data from previous filter"); } } // Marks the all BlockingCollection<T> instances as not accepting any more additions if (outputValues != null) { foreach (var bc in outputValues) { bc.CompleteAdding(); } } }
public void Run() { Console.WriteLine("{0} is running", Name); while (!_input.All(i => i.IsCompleted) && !_token.IsCancellationRequested) { TInput receivedItem; int i = BlockingCollection <TInput> .TryTakeFromAny(_input, out receivedItem, 50, _token); if (i >= 0) { if (Output != null) { TOutput outputItem = _processor(receivedItem); BlockingCollection <TOutput> .AddToAny(Output, outputItem); Console.WriteLine("{0} sent {1} to next,线程id {2}", Name, outputItem, Thread.CurrentThread.ManagedThreadId); Thread.Sleep(TimeSpan.FromMilliseconds(100)); } else { _outputProcessor(receivedItem); } } else { Thread.Sleep(TimeSpan.FromMilliseconds(50)); } } if (Output != null) { foreach (var bc in Output) { bc.CompleteAdding(); } } }
public void Run() { Console.WriteLine("filter {0} is running", this.Name); while (!m_inputData.All(bc => bc.IsCompleted)) { TInput receivedItem; int i = BlockingCollection <TInput> .TryTakeFromAny( m_inputData, out receivedItem, 50); if (i >= 0) { if (m_outputData != null) { TOutput outputItem = m_function(receivedItem); BlockingCollection <TOutput> .AddToAny(m_outputData, outputItem); Console.WriteLine("{0} sent {1} to next filter", this.Name, outputItem); } else { m_outputAction(receivedItem); } } else { Console.WriteLine("Could not get data from previous filter"); } } if (m_outputData != null) { foreach (var bc in m_outputData) { bc.CompleteAdding(); } } }
public void Run() { Console.WriteLine("{0} is running", this.Name); while (!m_input.All(bc => bc.IsCompleted) && !m_token.IsCancellationRequested) { TInput receivedItem; int i = BlockingCollection <TInput> .TryTakeFromAny( m_input, out receivedItem, 50, m_token); if (i >= 0) { if (m_output != null) // we pass data to another blocking collection { TOutput outputItem = m_processor(receivedItem); BlockingCollection <TOutput> .AddToAny(m_output, outputItem); Console.WriteLine("{0} sent {1} to next", this.Name, outputItem); } else // we're an endpoint { m_outputProcessor(receivedItem); } } else { Console.WriteLine("Unable to retrieve data from previous filter"); } } if (m_output != null) { foreach (var bc in m_output) { bc.CompleteAdding(); } } }
public void AddAnyCancellable() { const int elNumber = 5; const int colNumber = 5; var cols = new BlockingCollection <int> [colNumber]; for (var i = 0; i < colNumber; i++) { cols[i] = new BlockingCollection <int> (elNumber); } var token = new CancellationTokenSource(1000); for (var i = 0; i < colNumber * elNumber; i++) { BlockingCollection <int> .AddToAny(cols, 1, token.Token); } foreach (var col in cols) { Assert.AreEqual(elNumber, col.Count); } }
public static async Task ThrottleProcessingAsync <T>(this IEnumerable <T> inputs, int parallel, Func <T, Task> process) { var queues = new BlockingCollection <T> [parallel]; var tasks = new Task[parallel]; for (int i = 0; i < parallel; i++) { var queue = queues[i] = new BlockingCollection <T>(1); tasks[i] = Task.Run(async() => { foreach (var input in queue.GetConsumingEnumerable()) { await process(input).ConfigureAwait(false); } }); } try { foreach (var input in inputs) { BlockingCollection <T> .AddToAny(queues, input); } foreach (var queue in queues) { queue.CompleteAdding(); } await Task.WhenAll(tasks).ConfigureAwait(false); } finally { foreach (var queue in queues) { queue.Dispose(); } } }
public void Run() { // Run while all the input BlockingCollection instances IsCompleted is false // and no cancellation was requested while ((!Input.All(inputBC => inputBC.IsCompleted)) && (!_token.IsCancellationRequested)) { TInput item; int i = BlockingCollection <TInput> .TryTakeFromAny( Input, out item, TIMEOUT, _token); if (i >= 0) { if (Output != null) { // Process the item TOutput result = _processor(item); // Add the result to any of the output collections BlockingCollection <TOutput> .AddToAny(Output, result, _token); } else { // The code is running the last consumer _outputProcessor(item); } } } if (Output != null) { // All the BlockingCollection instances finished foreach (var outputBC in Output) { outputBC.CompleteAdding(); } } }
public void MainTest() { var cts = new CancellationTokenSource(); Task.Run(() => { if (Console.ReadKey().KeyChar == 'C') { cts.Cancel(); } }); var sourceArrays = new BlockingCollection <int> [CollectionsNumber]; for (int i = 0; i < sourceArrays.Length; i++) { sourceArrays[i] = new BlockingCollection <int>(Count); } var filter1 = new PipelineWorker <int, decimal>(sourceArrays, (n) => Convert.ToDecimal(n * 0.97), cts.Token, "filter1"); var filter2 = new PipelineWorker <decimal, string>(filter1.Output, (s) => string.Format("--{0}--", s), cts.Token, "filter2"); var filter3 = new PipelineWorker <string, string>(filter2.Output, (s) => WriteLine($"The final result is {s} on thread id {Thread.CurrentThread.ManagedThreadId}"), cts.Token, "filter3"); try { Parallel.Invoke(() => { Parallel.For(0, sourceArrays.Length * Count, (j, state) => { if (cts.Token.IsCancellationRequested) { state.Stop(); } int k = BlockingCollection <int> .AddToAny(sourceArrays, j); if (k >= 0) { WriteLine($"added{j} to souce Data on thread id {Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(TimeSpan.FromMilliseconds(100)); } }); foreach (var arr in sourceArrays) { arr.CompleteAdding(); } }, () => filter1.Run(), () => filter2.Run(), () => filter3.Run() ); } catch (AggregateException ae) { foreach (var ex in ae.InnerExceptions) { WriteLine(ex.Message + ex.StackTrace.ToString()); } } if (cts.Token.IsCancellationRequested) { WriteLine($"Operation has been canceled! Press Enter to exit."); } else { WriteLine("Press Enter to exit."); } //Console.ReadLine(); }
public void Dispatch(Http http) { BlockingCollection <Http> .AddToAny(_requestQueues, http); }
private static void Main() { // Создаем 2 блокирующие коллекции для передачи строк var bc1 = new BlockingCollection <string>(); var bc2 = new BlockingCollection <string>(); // Создаем другую блокирующую коллекцию, которая будет использоваться для передачи целых чисел var bc3 = new BlockingCollection <string>(); // Создаем два массива блокирующих коллекций BlockingCollection <string>[] bcland2 = { bc1, bc2 }; BlockingCollection <string>[] bcAll = { bc1, bc2, bc3 }; var tokenSource = new CancellationTokenSource(); // Создаем первый набор производителей for (int i = 0; i < 5; i++) { Task.Factory.StartNew(() => { while (!tokenSource.IsCancellationRequested) { string message = string.Format("Message from task {0}", Task.CurrentId); // Добавляем сообщение в одну из двух доступных коллекций BlockingCollection <string> .AddToAny(bcland2, message, tokenSource.Token); tokenSource.Token.WaitHandle.WaitOne(1000); } }, tokenSource.Token); } // Создаем второй набор производителей for (int i = 0; i < 3; i++) { Task.Factory.StartNew(() => { while (!tokenSource.IsCancellationRequested) { string warning = string.Format("Warning from task {0}", Task.CurrentId); bc3.Add(warning, tokenSource.Token); tokenSource.Token.WaitHandle.WaitOne(500); } }, tokenSource.Token); } // Создаем потребителей for (int i = 0; i < 2; i++) { Task.Factory.StartNew(() => { while (!tokenSource.IsCancellationRequested) { string item; int bcid = BlockingCollection <string> .TakeFromAny(bcAll, out item, tokenSource.Token); Console.WriteLine("From collection {0}: {1}", bcid, item); } }, tokenSource.Token); } Console.WriteLine("Press enter to cancel tasks"); Console.ReadLine(); tokenSource.Cancel(); Console.WriteLine("Press enter to finish"); Console.ReadLine(); }
static void Main(string[] args) { // create a pair of blocking collections // that will be used to pass strings BlockingCollection <string> bc1 = new BlockingCollection <string>(); BlockingCollection <string> bc2 = new BlockingCollection <string>(); // create another blocking collection // that will be used to pass ints BlockingCollection <string> bc3 = new BlockingCollection <string>(); // create two arrays of the blocking collections BlockingCollection <string>[] bc1and2 = { bc1, bc2 }; BlockingCollection <string>[] bcAll = { bc1, bc2, bc3 }; // create a cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the first set of producers for (int i = 0; i < 5; i++) { Task.Factory.StartNew(() => { while (!tokenSource.IsCancellationRequested) { // compose the message string message = String.Format("Message from task {0}", Task.CurrentId); // add the message to either collection BlockingCollection <string> .AddToAny(bc1and2, message, tokenSource.Token); // put the task to sleep tokenSource.Token.WaitHandle.WaitOne(1000); } }, tokenSource.Token); } // create the second set of producers for (int i = 0; i < 3; i++) { Task.Factory.StartNew(() => { while (!tokenSource.IsCancellationRequested) { // compose the message string warning = String.Format("Warning from task {0}", Task.CurrentId); // add the message to either collection bc3.Add(warning, tokenSource.Token); // put the task to sleep for 500ms tokenSource.Token.WaitHandle.WaitOne(500); } }, tokenSource.Token); } // create the consumers for (int i = 0; i < 2; i++) { Task consumer = Task.Factory.StartNew(() => { string item; while (!tokenSource.IsCancellationRequested) { // take an item from any collection int bcid = BlockingCollection <string> .TakeFromAny(bcAll, out item, tokenSource.Token); // write out the item to the console Console.WriteLine("From collection {0}: {1}", bcid, item); } }, tokenSource.Token); } // prompt the user to press enter Console.WriteLine("Press enter to cancel tasks"); Console.ReadLine(); // cancel the token tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Press enter to finish"); Console.ReadLine(); }
public void ReadAll(Func <int, Release, bool> processor) { TaskCreationOptions taskOptions = TaskCreationOptions.LongRunning; Task[] consumers = new Task[this.ThreadCount]; for (int i = 0; i < consumers.Length; ++i) { consumers[i] = Task.Factory.StartNew(delegate(object state) { int threadNumber = (int)state; int count = 0; try { string[] stringBatch; while (true) { BlockingCollection <string[]> .TakeFromAny(stringCollection, out stringBatch, cancellationToken); foreach (string releaseStringOriginal in stringBatch) { // Remove <releases>...</releases> string releaseString = Utility.TrimString(releaseStringOriginal, "<releases>"); releaseString = Utility.TrimString(releaseString, "</releases>"); var fixedText = Utility.FixXmlText(releaseString); XDocument doc = XDocument.Parse(fixedText); var release = DataReader.ReadRelease(doc.Root); ++count; if (!processor(threadNumber, release)) { cancellationSource.Cancel(); throw new OperationCanceledException(); } } } } catch (OperationCanceledException) { } catch (InvalidOperationException) { } catch (ArgumentException) { } }, i, taskOptions); } Task stringProducer = Task.Factory.StartNew(delegate { try { string[] stringBatch; while (ReadBatch(BatchSize, out stringBatch)) { BlockingCollection <string[]> .AddToAny(stringCollection, stringBatch, cancellationToken); } } catch (OperationCanceledException) { } catch (InvalidOperationException) { } finally { foreach (var coll in stringCollection) { coll.CompleteAdding(); } } }, taskOptions); Task dataReader = Task.Factory.StartNew(delegate { try { int read = 0; char[] NewBuffer = new char[BufferSize]; while ((read = reader.ReadBlock(NewBuffer, 0, BufferSize)) > 0) { bufferCollection.Add(new CharBuffer(NewBuffer, read), cancellationToken); NewBuffer = new char[BufferSize]; } } catch (OperationCanceledException) { } finally { bufferCollection.CompleteAdding(); } }, taskOptions); Task.WaitAll(consumers); stringProducer.Wait(); dataReader.Wait(); }