2015-02-12 84 views
0

該程序讀取網站列表,然後保存它們。 我發現它運行良好的前2個網址請求。然後變得非常緩慢(每個請求大約5分鐘)C#異步Web瀏覽器運行速度很慢

第1行和第2行花費的時間只有2秒。 然後所有其他的將是每個約5分鐘。

當我調試,我看到它實際上tooks長wb.Navigate(url.ToString());

public static async Task<bool> test() 
    { 

     long totalCnt = rows.Count(); 
     long procCnt = 0; 
     foreach (string url in rows) 
     { 
      procCnt++; 

      string webStr = load_WebStr(url).Result; 
      Console.WriteLine(DateTime.Now+ "["+procCnt + "/" + totalCnt+"] "+url); 
     } 



     return true; 
    } 


public static async Task<string> load_WebStr(string url) 
{ 
    var tcs = new TaskCompletionSource<string>(); 

    var thread = new Thread(() => 
    { 
     EventHandler idleHandler = null; 

     idleHandler = async (s, e) => 
     { 
      // handle Application.Idle just once 
      Application.Idle -= idleHandler; 

      // return to the message loop 
      await Task.Yield(); 

      // and continue asynchronously 
      // propogate the result or exception 
      try 
      { 
       var result = await webBrowser_Async(url); 
       tcs.SetResult(result); 
      } 
      catch (Exception ex) 
      { 
       tcs.SetException(ex); 
      } 

      // signal to exit the message loop 
      // Application.Run will exit at this point 
      Application.ExitThread(); 
     }; 

     // handle Application.Idle just once 
     // to make sure we're inside the message loop 
     // and SynchronizationContext has been correctly installed 
     Application.Idle += idleHandler; 
     Application.Run(); 
    }); 

    // set STA model for the new thread 
    thread.SetApartmentState(ApartmentState.STA); 

    // start the thread and await for the task 
    thread.Start(); 
    try 
    { 
     return await tcs.Task; 
    } 
    finally 
    { 
     thread.Join(); 
    } 

} 


public static async Task<string> webBrowser_Async(string url) 
{ 

    string result = ""; 
    using (var wb = new WebBrowser()) 
    { 
     wb.ScriptErrorsSuppressed = true; 

     TaskCompletionSource<bool> tcs = null; 
     WebBrowserDocumentCompletedEventHandler documentCompletedHandler = (s, e) => 
     tcs.TrySetResult(true); 


     tcs = new TaskCompletionSource<bool>(); 
     wb.DocumentCompleted += documentCompletedHandler; 
     try 
     { 
      wb.Navigate(url.ToString()); 
      // await for DocumentCompleted 
      await tcs.Task; 
     } 
     catch 
     { 
      Console.WriteLine("BUG!"); 

     } 
     finally 
     { 
      wb.DocumentCompleted -= documentCompletedHandler; 
     } 
     // the DOM is ready 

     result = wb.DocumentText; 

    } 


    return result; 
} 
+0

呃......很確定你的任務永遠不會完成。在完成之前移除'DocumentCompleted'處理程序。 – Aron 2015-02-12 02:09:33

回答

0

我認識的代碼稍加修改的版本,我曾經回答了不少WebBrowser - 相關問題。是this one?包含指向原始來源的鏈接始終是一個好主意。

無論如何,您在這裏如何使用它的主要問題可能是您創建並銷燬了列表中每個URL的WebBrowser控件實例。

相反,您應該重新使用WebBrowser(或WebBrowser對象池)的單個實例。您可以找到兩個版本here