2017-03-01 4 views
1

Ich bin neu in der Verwendung von asynchronen Methoden, also denke ich, dass ich etwas falsch verstehe. Ich habe eine WinForms-App mit einer Schaltfläche, und wenn auf die Schaltfläche geklickt wird, wird eine asynchrone Methode aufgerufen. Dies muss asynchron sein, da ich JavaScript-Aufrufe an ein Chromium Web Browser-Steuerelement (mit CefSharp) vornehmen muss. Ich muss sicherstellen, dass dieses Javascript ausgeführt wurde und dass der Browser aktualisiert wurde, bevor Sie mit dem nächsten Teil der Methode fortfahren.Verwenden Sie in asynchronen Methoden warten, um zu verhindern, dass die nächste Codezeile ausgeführt wird

Ich versuche im Grunde, die gesamte Webseite in einem einzigen Bild zu erfassen. Mein Ansatz bestand darin, JavaScript zu verwenden, um die Bildlaufposition auf der Seite zu aktualisieren, und dann Screenshots an jeder Position mit Graphics.CopyFromScreen zu erstellen. Dies funktioniert meistens, aber gelegentlich hat das resultierende Bild den falschen "Brocken" der Webseite (z. B. wird die erste Bitmap zweimal wiederholt). Hier ist mein Code:

// Calculate screen sizes, screenshot spacing etc. 

for (int i = 0; i < screenshotCount; i++) 
{ 
    int scrollSize = i == 0 ? -PageHeight : (int)browserControlHeight; 
    string script = "(function() { window.scrollBy(0, " + scrollSize.ToString() + ") })();"; 

    await browser.EvaluateScriptAsync(script); 

    // Take screenshot, add to list of bitmaps 
} 

// Combine resulting list of bitmaps 

Wenn ich die folgenden

await Task.Delay(1000); 

nach dem EvaluateScriptAsync() -Aufruf hinzufügen, kommt das endgültige Bild als richtig jedes Mal. Ich gehe davon aus, dass das Javascript aufgerufen wird, aber nicht abgeschlossen wird, bevor der Screenshot beginnt. Wenn dies der Fall ist, funktioniert möglicherweise sogar das Hinzufügen einer Verzögerung nicht (was ist, wenn das JavaScript länger als eine Sekunde zum Ausführen benötigt?).

Bin ich falsch verstanden, wie async/wait funktioniert?

Antwort

5

Nein, ist das Problem nicht mit await, das Problem ist, dass die Task von EvaluateScriptAsync zurück markiert wird als abgeschlossen, bevor Sie bereit sind, fortzusetzen. Es wird als abgeschlossen markiert, sobald das Javascript dem Browser mitteilt, dass es scrollen soll, statt als abgeschlossen markiert zu werden, nachdem der Browser den Bildschirm nach dem Senden des Bildlaufbefehls erneut gerendert hat.

+0

Also, wenn ich eine zusätzliche Zeile zu dem JavaScript hinzufügen, die ausgeführt wird, um einfach wahr zurückzugeben, würde das das Problem lösen? In Javascript vorausgesetzt, dass die nächste Zeile nicht ausgeführt wird, bis der Bildlauf abgeschlossen ist. – jardantuan

+1

@jardantuan Diese zweite Annahme ist nicht wahr. Das ist die Wurzel Ihres Problems an erster Stelle. Wenn diese Annahme zutrifft, würde Ihr Code bereits funktionieren. – Servy

+0

Das macht Sinn. Im Moment denke ich, ich könnte einen Haken in das Javascript einfügen, das sehen würde, ob sich die Scroll-Position geändert hat, und dann etwas zurückgeben - würde das funktionieren? Es ist auch möglich, dass ich eine viel offensichtliche Lösung vermisse. – jardantuan

Verwandte Themen