4

StreamReader私は(たとえば)aまたは。の上にあるインターフェースを使用していますSqlDataReader。インターフェイスはメソッドを公開します。このメソッドGetNext()は、オブジェクトが残っている場合、またはオブジェクトが残っていない場合にオブジェクトを返しますnull

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

T返されるそれぞれGetNext()を並行して処理し、 GetNext()返されるときに処理を停止する必要がありますnull。これがどのように行われるのか(TPLなどを使用して)よくわかりません。一種の並列が必要whileです!明らかに、取得したときにまだ処理中のスレッドを終了さnullせたくありません。新しい処理を追加したくないだけです。次に、すべてのスレッドが実行中の処理を終了したときに「ループ」から脱退します。 。

誰か助けてもらえますか?私の質問が意味をなさない場合は私に知らせてください。

4

3 に答える 3

5

あなたが示しているような「コレクション」は、通常、 を介して公開されることに注意してくださいIEnumerable<T>。API 自体を制御できる場合は、ベースの反復アプローチIEnumerable<T>の代わりに使用します。GetNext()ただし、そうでない場合は、変換を実行するのは簡単です...

この API をラップして、IEnumerable<T>. 次に使用できますParallel.ForEach

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

その後、次を使用できます。

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

これにより、ウィジェットを列挙する際のスレッド化の問題が回避されますが (列挙子はシングル スレッドになるため)、コレクションを並行して処理できます。

于 2012-10-01T16:48:02.623 に答える
1

イテレータを作成するだけです。

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;
    }
}

で使用しますParallel

        var widget = new CollectionWidget();

        Parallel.ForEach(widget.GetItems(), i => Console.WriteLine(i));
于 2012-10-01T16:49:47.913 に答える
-1

使用することもできます

Task.Factory.StartNew()
于 2012-10-01T16:49:32.560 に答える