Wie erfolgt die Warteschlange Elemente seriell auf einem Thread niedriger Priorität verwendet Parallel Extensions verarbeiten

StackOverflow https://stackoverflow.com/questions/4252634

Frage

Ich möchte wissen, was der beste Weg, um die Ergebnisse eines langlaufende Prozess seriell zu verarbeiten, sondern auf einem mit niedriger Priorität Thread mit der . NET 4.0 Parallel Extensions .

Ich habe die folgende Klasse, dass sowohl die Ausführung tut und liefert die Ergebnisse:

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

Wie kann ich diese Schritte verarbeiten und auch in einer Datei speichern, um, nachdem sie verarbeitet werden? Ich mag sie in eine Datei speichern, während RemotedService.DoSomeStuff() auf eine Antwort vom Server warten.

Das Schreiben in die Datei so sein würde:

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

Eine Möglichkeit, die in den Sinn kommt, ist sie zu einem Queue hinzuzufügen und haben eine Timer, dass Prozesse sie. Dabei wird jedoch nicht die Vorteile der Ausfallzeiten der remoted Anrufe.

Eine weitere Option, die den Sinn kommt, ist asynchron jedes Ergebnis an die eine System.Threading.Tasks.Task pro Step Datei schreiben verwenden, aber das ist keine Garantie, dass sie in Ordnung gespeichert werden und auch Konkurrenz einführen in die Datei mit dem Schreiben.

War es hilfreich?

Lösung

Ich würde vorschlagen, ein BlockingCollection<Step> Schaffung (System.Collections.Concurrent Namespace sehen). Da jeder Schritt abgeschlossen ist, wird es zu dieser Sammlung hinzugefügt. Das Standardverhalten von BlockingCollection ist, um als eine Warteschlange, so dass Sie das FIFO-Verhalten bekommen Sie suchen.

Ein zweiter Thread Dienste der Warteschlange, jedes Element zu entfernen und in eine Protokolldatei geschrieben werden.

Wenn Sie also die Warteschlange hinzugefügt:

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

Sie möchten fügen Sie diese zu Ihrer Execute Methode, nachdem das Einzelteil abgeschlossen ist:

LogQueue.Add(this);

Und Ihr Logging-Thread, die Sie im statischen Konstruktor beginnen würden:

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

Der Logging-Thread, wie ich es geschrieben habe, verwendet einen System.Threading Thread. Es könnte ein einfacher oder besserer Weg, es mit TPL zu tun. Ich bin noch nicht schrecklich vertraut mit TPL, so konnte ich nicht sagen.

Andere Tipps

Ein Ansatz ist es, ein benutzerdefinierten Taskplaner (siehe http zu erstellen: // msdn .microsoft.com / en-us / library / ee789351.aspx ). Ihr benutzerdefinierter Task-Scheduler Gleichzeitigkeit eines-at-a-time begrenzen und Durchsetzung strenger in Ordnung Ausführung.

auch einen Taskplaner erstellen, können Sie die Thread-Priorität steuern, oder die Apartment was in manchen Situationen wünschenswert sein kann.

Sie beschreiben wahrsten Sinne des Wortes den Anwendungsfall für Workflow Foundation - es ist all dieses Zeug für Sie:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top