2016-12-11 5 views
2

マルチスレッドに関する質問があります。多分問題は簡単に解決されますが、私はどの方法が最善であるかわかりません! :)特定の順序のコレクションからのマルチスレッド処理アイテムC#

私はいくつかの要素のコレクションを持っています。例えば、Listです。

このコレクションには次の要素が含まれているとします:
SportEventSettings_1;
SportEventSettings_2;
SportEventSettings_3;
SportEventSettings_4;
SportEventSettings_5;

私は別のスレッドで、このコレクションを処理し、顧客に送信するための.NETのタスク並列ライブラリからParalle.ForEach methofを使用しています。しかし、この場合、私たちは、私たちの側で処理した後、同じ順序で顧客に送信されるcolectionからのこれらの要素を約束することはできません。どのようにしてこれを決め、コレクションの注文に従ってこのアイテムを送るのですか?

P.S.重要ではない(!!!)私たちの側で注文を処理します。しかし重要なのは、リストと同じ順序でリストアイテムを送信することです。

ありがとうございます! :)

+0

は、メッセージのasynchroneを進めるが、あなたが必要とするためには、正確な彼らにsynchroneウントを送信する必要があります。 –

+0

[Parallel.ForEach Ordered Execution]の重複の可能性があります(http://stackoverflow.com/questions/3639768/parallel-foreach-ordered-execution) – jdphenix

答えて

5

使用。 AsParallel()Parallel.ForEach()の代わりにAsOrdered()です。これにより、項目を並行して処理することができ、入力順に表示されるのと同じ順序で処理された項目が列挙されます。

var inputItems = new List<int>(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 });//List<int> is just example, input sequence can be any IEnumerable<T> 

var processedItems = inputItems 
    .AsParallel()//Allow parallel processing of items 
    .AsOrdered()//Force items in output enumeration to be in the same order as in input 
    .WithMergeOptions(ParallelMergeOptions.NotBuffered)//Allows enumeration of processed items as soon as possible (before all items are processed) at the cost of slightly lower performace 
    .Select(item => 
     { 
      //Do some processing of item 
      Console.WriteLine("Processing item " + item); 

      return item;//return either input item itself, or processed item (e.g. item.ToString()) 
     }); 

//You can use processed enumeration just like any other enumeration (send it to the customer, enumerate it yourself using foreach, etc.), items will be in the same order as in input enumeration. 
foreach (var processedItem in processedItems) 
{ 
    //Do whatever you want with processed item 
    Console.WriteLine("Enumerating item " + processedItem); 
} 
0

あなたはずっとあなたがConcurrentQueue<T>のようなものを使用することができるようにするため気にならば、あなたがアイテムを削除するときに注意する必要があるので、しかし、これはFIFOロジックです。

完全に柔軟なオプションをお探しの場合は、BlockingCollection<T>もあります。このような場合は非常に便利です。 Hereは良い記事で、thisは元のMS docです。リストから項目を取得しようとしたときにケースを見ることができます下

:この場合

BlockingCollection<MyClass> bCollection = new BlockingCollection<MyClass>(boundedCapacity: 2); 
bCollection.Add(new MyClass{ Field1 = "Test" }); 
bCollection.Add(new MyClass{ Field1 = "Test2" }; 

var item = bCollection.Take(); 
item = bCollection.Take(); 

if (bCollection.TryTake(out item, TimeSpan.FromSeconds(1))) 
{ 
    Console.WriteLine(item); 
} 
else 
{ 
    Console.WriteLine("No item removed"); 
} 
関連する問題