2016-03-21 4 views
0

Ich drucke einen Bericht in C#, der Bericht hat viele Seiten, auf denen jede Seite komplexe Berechnungen hat. weil es viele Seiten geben kann und jede Seite so lange dauern kann, würde ich die Berechnung asynchron machen. Weil dies ein technisches Problem für ein Codierungsproblem ist, entfernte ich alle Unordnung. das ist, was mein Code kommt darauf an:So stoppen Sie den Druckvorgang, bis die Berechnung der Seiten abgeschlossen ist

private void StartPrinting(object sender, PrintPageEventArgs e) 
    { 


    // calculate the total width and height of the printing area of the page 

    // -1 just to be conservative 
    documentWidth = CalculateDocumentWidth(printDocument, e) - 1; 
    // -1 just to be conservative 
    documentHeight = CalculateDocumentHeight(printDocument, e) - 1; 

    // calculate the columns and rows of all pages 
    // some calculations .... 

    // delegate to get results back 
    DelegateToReportVoPageStructureDescription theDelegate 
     = ReportPageObjectCalculatedHandler; 


    for (int i = 0; i < pageStructureObjects.Count; i++) 
    { 

     Task.Run(() => 
     { 
      // call method to calculate each page here .... 
      // results returned by delegate to 
      // ReportPageObjectCalculatedHandler mehtod 
     }); 

    } 

    } 

den Berichtsseiten für Schleife berechnen jeweils in separaten Thread dann das Ergebnis jeder Berechnungsprozess der folgenden Methode kommt:

public void ReportPageObjectCalculatedHandler(VoReportPageObject voReportPageObject, int pageIndex) 
    { 

    lock (thisLock) // thread safety 
    { 
     // assign the calculated page to local variable 

     // count how many pages finished calculation 

    } 

    if (all pages finished) 
    { 
     // now i can start printing 
    } 
    } 

nur, wenn alle Seiten wurde verarbeitet ich kann mit dem Drucken fortfahren. Jetzt können Sie fragen, warum ich nicht die ganze Berechnung mache, bevor ich den Druckprozess auslöst? Das ist, weil ich die Dimensionen der Seite benötige, bevor ich irgendeine Verarbeitung machen kann.

Ich kann eine Schleife nach dem Task.Run (() - Block machen, um zu prüfen, ob alle Seiten berechnet wurden, aber das ist nicht gut. Ich brauche eine Möglichkeit, den Druck zu stoppen, bis alle Seiten berechnet sind.

, wie kann ich dieses Problem lösen

Antwort

1

Sie können die Aufgaben des Task.Run Anruf in einem Array zurück sammeln und Task.WaitAll verwenden:

var tasks = new Task[pageStructureObjects.Count]; 
for (int i = 0; i < pageStructureObjects.Count; i++) 
{ 
    tasks[i] = Task.Run(() => 
    { 
     // call method to calculate each page here .... 
     // results returned by delegate to 
     // ReportPageObjectCalculatedHandler mehtod 
    }); 
} 
Task.WaitAll(tasks); 

Aber was Sie scheint dabei ein perfekter Kandidat fürzu sein:

Parallel.For(0, pageStructureObjects.Count, i => 
{ 
    // call method to calculate each page here .... 
    // results returned by delegate to 
    // ReportPageObjectCalculatedHandler mehtod 
}); 
+0

„Parallel.For“ wird warten, bis alle Fäden an den Rest des Verfahrens vor dem Fortfahren zu vervollständigen? – docesam

+0

Dies ist, was es tut - läuft alles parallel, aber nach dem Ende ist alles abgeschlossen, wie nach einem regulären 'for' –

+0

Das ist super! Danke – docesam

Verwandte Themen