2017-01-14 43 views
-1

我試圖創建一個類,可以異步方式搜索網站列表中的字符串。異步與任務 - 通過網站列表搜索

下面的代碼工作,但我得到的感覺,它的工作完全錯誤:

public static class Searcher 
    { 

     public struct SearchResult 
     { 
      public SearchResult(string Url, bool Found) 
      { 
       this.Url = Url; 
       this.Found = Found; 
      }    

      public string Url; 
      public bool Found; 
     } 

     public async static Task<SearchResult> SearchWebsiteAsync(string url, string str) 
     { 
      HttpClient client = new HttpClient(); 
      var urlContents = await client.GetStringAsync(url); 

      System.Console.WriteLine("Found string in website {0}", url); 
      bool foundString = (urlContents.Contains(str) ? true : false); 

      return new SearchResult(url, foundString); 
     } 

     public static async Task<IEnumerable<SearchResult>> StartSearch(string str) 
     { 
      List<SearchResult> results = new List<SearchResult>(); 
      List<Task<SearchResult>> taskList = new List<Task<SearchResult>>(); 

      foreach (var url in TheWeb.URLs) 
      { 
       System.Console.WriteLine("Searching URL {0}", url); 

       var t = new Task<Task<SearchResult>>(() => SearchWebsiteAsync(url, str)); 
       t.Start(); 
       taskList.Add(t.Result); 
      } 
      //Task.WaitAll(tasks.ToArray()); 

      foreach (var task in taskList) { 
       results.Add(task.Result); 
      }    

      return results; 
     } 
    } 

尤其是,我有'內Task小號的Taskvar t = new Task<Task<SearchResult>>(() => SearchWebsiteAsync(url, str));

的是,有一個更好的方法(如果可能沒有Parallel,因爲我仍然試圖得到一些異步等待和任務的理解)

+0

如果代碼正在工作,那麼這更適合[代碼審查](https://codereview.stackexchange.com/)網站,這使得這是一個關鍵的問題。 – Nkosi

+1

'HttpClient'被設計爲可重用並且相對長壽;不要爲每個請求創建一個新的。 – sellotape

回答

2

從我的理解你的代碼,它並不真的不管搜索結果來自哪項任務(因爲無論如何,url都包含在搜索結果中)。

因此,如何

public static async Task<SearchResult[]> StartSearch(string str) 
{ 
    List<Task<SearchResult>> taskList = new List<Task<SearchResult>>(); 

    foreach (var url in TheWeb.URLs) 
    { 
     System.Console.WriteLine("Searching URL {0}", url); 
     taskList.Add(SearchWebsiteAsync(url, str)); 
    } 

    return await Task.WhenAll<SearchResult>(taskList); 
} 

async函數返回Task對象。你不需要new Task(() => {...})來初始化它們。只需調用async函數就足以獲得有效的Task對象。

我在這裏假設您可以同時獲取所有搜索結果。如果這個假設是不正確的,請讓我知道。還有其他解決方案可能。