2017-03-01 29 views
1

我是使用異步方法的新手,所以我認爲我誤解了某些東西。我有一個WinForms應用程序和一個按鈕,當點擊按鈕時,會調用一個異步方法。這必須是異步的,因爲我需要對Chromium Web瀏覽器控件(使用CefSharp)進行JavaScript調用。我需要確保此JavaScript已完成運行,並且在繼續執行下一部分方法之前瀏覽器已更新。在異步方法中使用await來防止下一行代碼運行

我基本上試圖將整個網頁捕捉到一個圖像。我的方法是使用JavaScript更新頁面上的滾動位置,然後使用Graphics.CopyFromScreen在每個位置截取屏幕截圖。這主要起作用,但是偶爾會導致圖像出現錯誤的網頁塊(例如,第一個位圖重複兩次)。這裏是我的代碼:

// 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 

如果我添加以下

await Task.Delay(1000); 
的EvaluateScriptAsync()調用後

,最終的圖像出來正確的每一次。我正在假設javascript正在被調用,但在截圖開始前沒有完成。如果是這種情況,即使增加一個延遲可能不起作用(如果JavaScript花費的時間超過一秒鐘,該怎麼辦?)。

我誤解異步/等待的方式嗎?

回答

5

不,問題不在於await,問題在於EvaluateScriptAsync返回的Task在您準備繼續之前被標記爲已完成。只要JavaScript通知瀏覽器它應該滾動已經執行,而不是在瀏覽器在發送滾動命令後重新呈現屏幕之後標記爲完成,它將被標記爲完成。

+0

因此,如果我添加一個額外的行到正在執行的JavaScript只是返回true,會解決這個問題嗎?假設在JavaScript中,下一行將不會運行,直到滾動完成。 – jardantuan

+1

@jardantuan第二個假設是不正確的。這首先是你問題的根源。如果這個假設是真的,那麼你的代碼已經可以工作了。 – Servy

+0

這是有道理的。此刻,我想我可以在javascript中添加一個支票,以查看滾動位置是否發生了變化,然後返回一些內容 - 是否可行?也有可能我錯過了一個更明顯的解決方法。 – jardantuan

相關問題