2017-01-14 3 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; 
     } 
    } 

私はS「のTask内のS」のTaskを持っている。特にこと:var 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(() => {...})は必要ありません。有効なTaskオブジェクトを取得するには、async関数を呼び出すだけで十分です。

ここでは、すべての検索結果を同時に取得することができます。その前提が間違っている場合は、私に知らせてください。他にも解決策があります。