Like parallel process inputs until a condition is true in C #

I work with an interface that sits on top (for example) of a StreamReader or SqlDataReader . The interface provides a GetNext() method that returns an object if there are any left or null if there are any left.

 public interface ICollectionWidget<T> { T GetNext(); // Returns a T if there are any left, or null if there aren't } 

I need to process every T returned by GetNext() in parallel, and stop processing when GetNext() returns null . I'm not quite sure how this is done (using TPL or something else). I need some parallel while ! Obviously, I don't want any threads that were still being processed to end when I get null , I just don't want to add any new processing, and then drop out of the loop when all the threads finish what they are I do.

Can anyone help? Please let me know if my question does not make sense.

+4
source share
3 answers

Note that โ€œcollectionsโ€ like the one you are displaying are usually exposed through IEnumerable<T> . If you have control over the API itself, I would use IEnumerable<T> instead of an approach based on GetNext() . However, if you do not, just do the conversion ...

I would wrap this API to show it as an IEnumerable<T> . Then you can use Parallel.ForEach :

 private IEnumerable<T> EnumerateWidgets<T>(ICollectionWidget<T> widgets) { T element = widgets.GetNext(); while (element != null) { yield return element; element = widgets.GetNext(); } } 

Then you can use:

 Parallel.ForEach(EnumerateWidgets(widgetCollection), widget => { // Process widget here }); 

This will prevent threading issues when listing your widgets (since the listing will be single-threaded), but you can process your collection in parallel.

+5
source

Just do an iterator:

 public interface ICollectionWidget<T> { IEnumerable<T> GetItems(); } public class CollectionWidget : ICollectionWidget<int> { public IEnumerable<int> GetItems() { var i = 0; while (i++ < 10) { yield return i; } yield break; } } 

and use it in Parallel :

  var widget = new CollectionWidget(); Parallel.ForEach(widget.GetItems(), i => Console.WriteLine(i)); 
+1
source

You can also use

 Task.Factory.StartNew() 
-1
source

Source: https://habr.com/ru/post/1437240/


All Articles