2017-08-25 3 views
0

Ich habe eine Anforderung, wo ein Client eine Anfrage an eine einzelne Webseite stellt, diese Webseite muss die Ergebnisse von zwei anderen Webseiten abrufen.Mehrere Hintergrundarbeiter in Webformular-Anwendung

Die beiden Webseiten, von denen wir Informationen anfordern, führen einen Prozess aus, bevor das Ergebnis zurückgegeben wird. Dieser Vorgang kann einige Minuten dauern, anstatt eine Webanforderung zu starten und darauf zu warten, dass sie erneut gestartet wird feuern Sie beide Anfragen im Hintergrund ab und lassen Sie die Ergebnisse parallel generieren.

So sieht mein Code so etwas wie dieser (Pseudo-Code):

var worker1 = new BackgroundWorker(); 
var worker2 = new BackgroundWorker(); 

worker1.DoWork += (s, e) => { 
//Web Request done here 
}; 

worker2.DoWork += (s, e) => { 
    //Web Request done here 
}; 

worker1.RunWorkerAsync(); 
worker2.RunWorkerAsync(); 

//Some logic here that basically waits for both to return. 

Jetzt bemerkte ich, dass die Ergebnisse noch mehr einnahmen zurückzukehren, als ich erwartete, so habe ich ein bisschen einen Test und verändern den Inhalt der DoWork zu

using (var sw = new StreamWriter(@"c:\temp\TEST\Worker1.txt")) 
{ 
    for (int i = 0; i < 1000000; i++) 
    { 
     sw.WriteLine($"{i} - {DateTime.Now.ToLongTimeString()}"); 
    } 
} 

der Kürze halber wird nicht kopiere ich diese wieder aus, aber davon ausgehen, dass der Dateiname worker2.txt in die zweite Arbeiter DoWork geändert wird()

Seine grobe ich weiß, aber es funktioniert, es dauert etwa 3 Sekunden, um die Zeit 1 Million mal zu schreiben, so in der ersten Datei sehe ich Zeiten von Ausführungszeit bis zur Ausführung + 3 Sekunden In der zweiten Datei kann ich mal sehen von Ausführungszeit + 3 Sekunden bis zur Ausführungszeit + 6 Sekunden.

So ist an dieser Stelle klar, dass ein Arbeiter zuerst und dann der andere ausgeführt wird, aber ich kann nicht sehen, warum.

Mehr Informationen über das Projekt - Web-Formulare (Dies ist eine Voraussetzung mir gegeben wurde und halten müssen) .net 4.5

** hinzufügen Editiert: **

Nach der Rückkehr zu Dieses Problem Ich habe einen Blick auf die Seiten geworfen, die ich anrufe, und bemerke, dass sie aspcompat = true in der Seitendeklaration haben, von der ich annehme, was das Problem verursacht (Sie benötigen das, ich kann es nicht entfernen).

Was sind meine Optionen jetzt? Idealerweise möchte ich in der Lage sein, diese Seiten parallel laufen zu lassen, gibt es eine Möglichkeit, dies zu erreichen, wenn aspcompat auf true gesetzt ist?


Bearbeitung für zukünftige Leser

Beachten Sie, dass das Problem, das ich oben beschrieben und der Code, der korrekt waren vorgesehen war, war die Frage, die ich hatte, dass die Seiten, die ich wurden eingestellt rief zu Verwenden Sie ASPCOMPAT, das Webforms dazu zwingt, im STA-Modus zu arbeiten, was mich abschreckte.

Am Ende arbeitete der obige Code unverändert, die Lösung bestand darin, die Seite mit den Hintergrundarbeitern in eine separate Webanwendung mit eigenem App-Pool zu stellen, auf der die n Hintergrundarbeiter auf die Seiten zugreifen konnten im ASPCOMPAT-Modus in ihrem Anwendungspool laufen - das ist nicht ideal, aber das, was wir sowieso für die Live-Bereitstellung wollten.

+0

Warum nicht nur async verwenden/warten? Vermeiden Sie den Hintergrund-Unsinn und dann 'Task.WaitAll()'. – axlj

+0

Gleiches Verhalten wie oben beschrieben. – D3vy

Antwort

0

Sie könnten die BackgroundWorker überspringen und stattdessen Task.WaitAll() verwenden.

void Main() 
{ 
    Task.WaitAll(FirstRequest(), SecondRequest()); 
} 

// Define other methods and classes here 
private async static Task FirstRequest() 
{ 
    // Do your work for one of the WebRequests here 
    await Task.Delay(3000); 
    Console.WriteLine("Done with 1"); 
} 

private async static Task SecondRequest() 
{ 
    // Do your work for the second WebRequest here 
    await Task.Delay(3000); 
    Console.WriteLine("Done with 2"); 
} 
+0

Mein erster Gedanke war, eine asynchrone Methode zu verwenden und darauf zu warten, aber das wird das gleiche Verhalten. Aktualisiere die Frage mit etwas, das ich gerade auf den Seiten gesehen habe, die ich anrufe. – D3vy

Verwandte Themen