1

.NET 4.0 Parallel Extensionsを使用して、長時間実行されるプロセスの結果を優先度の低いスレッドでシリアルに処理する最良の方法を知りたいです。

実行と結果の両方を提供する次のクラスがあります。

public class Step 
{
  public string Name { get; set; }
  public TimeSpan Duration { get; set; }
  public bool Completed { get; set; }

  public void Execute() 
  {
     DateTime before = DateTime.Now;
     RemotedService.DoSomeStuff();
     Duration = DateTime.Now - before;
     Completed = true;
  }
}

これらのステップを処理し、処理後に順番にファイルに保存するにはどうすればよいですか? RemotedService.DoSomeStuff()サーバーからの応答を待っている間にファイルに保存したいと思います。

ファイルへの書き込みは次のようになります。

using (StreamWriter w = File.AppendText("myFile.txt"))
{
  var completedStep = completedSteps.Dequeue();
  w.WriteLine(string.Format("Completed {0} with result: {1} and duration {2}", 
                            completedStep.Name, 
                            completedStep.Completed, 
                            completedStep.Duration));
}

頭に浮かぶ 1 つのオプションは、それらを に追加し、それらを処理QueueするTimerを用意することです。ただし、これはリモート呼び出しのダウンタイムを利用していません。

頭に浮かぶ別のオプションは、System.Threading.Tasks.Taskperを使用して各結果をファイルに非同期に書き込むことですStepが、それは結果が順番に保存されることを保証するものではなく、ファイルへの書き込みで競合が発生する可能性もあります。

4

3 に答える 3

1

を作成することをお勧めします (名前空間BlockingCollection<Step>を参照)。System.Collections.Concurrent各ステップが完了すると、そのコレクションに追加されます。のデフォルトの動作はBlockingCollectionキューとして機能するため、探している FIFO の動作が得られます。

2 番目のスレッドがキューを処理し、各項目を削除してログ ファイルに書き込みます。

したがって、キューを追加した場合:

static private BlockingCollection<Step> LogQueue = new BlockingCollection<Step>();

Executeアイテムが完成した後、これをメソッドに追加します。

LogQueue.Add(this);

そして、静的コンストラクターで開始するログ スレッド:

static void LoggingThread()
{
    using (var w = new StreamWriter(...))
    {
        while (!LogQueue.IsCompleted())
        {
            Step item;
            if (LogQueue.TryTake(out item))
            {
                w.WriteLine(....);
            }
        }
    }
}

私が書いたログ スレッドは、System.Threadingスレッドを使用します。TPL でそれを行うためのより簡単またはより良い方法があるかもしれません。私はまだ TPL にあまり詳しくないので、何とも言えません。

于 2010-11-23T05:07:13.847 に答える
1

1 つの方法は、カスタム タスク スケジューラを作成することです ( http://msdn.microsoft.com/en-us/library/ee789351.aspxを参照)。カスタム タスク スケジューラは、同時実行を一度に 1 つに制限し、厳密な順序での実行を強制できます。

タスク スケジューラを作成すると、スレッドの優先度や、場合によっては望ましい ApartmentState を制御することもできます。

于 2010-11-24T23:58:49.403 に答える
0

あなたは文字通り Workflow Foundation の使用例を説明しています - それはあなたのためにこのすべてを行います :)

于 2010-11-23T08:02:57.727 に答える