0

次の要件があります。

ダウンロードする必要がある URL の配列があります。

  1. 同時にダウンロードできるのは 3 つの URL のみです
  2. これら 3 つの URL の 1 つ (または複数) が完了した場合 - 配列から次の空き URL を取得する必要があります
  3. これら 3 つの URL の 1 つ (または複数) が X 時間内に完了しない場合 - この URL をキャンセルする必要があります
  4. URL の配列が終了した場合 - 現在のすべてのタスクが完了するまで待機し、1 つだけがメイン メソッドから移動します。

C# 5.0 でそれを行うには? 私は次のことをしようとします:

class Program
{
    static Stopwatch sw = Stopwatch.StartNew();

    static void Main(string[] args)
    {
        List<Task> tasks = new List<Task>();
        string[] urls = new string[] { "http://site1.ru", "http://www.site2.com", "http://site3.com", "http://site4.ru" };
        foreach (var url in urls)
        {
            var task = AsyncVersion(url);
            tasks.Add(task);
        }

        Task.WaitAll(tasks.ToArray());
    }

    static async Task AsyncVersion(string url)
    {
        var webRequest = WebRequest.Create(url);
        Console.WriteLine(
          "Перед вызовом webRequest.GetResponseAsync(). Thread Id: {0}, Url : {1}",
          Thread.CurrentThread.ManagedThreadId, url);
        var webResponse = await webRequest.GetResponseAsync();
        Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url,
          webResponse.ContentLength, sw.ElapsedMilliseconds,
          Thread.CurrentThread.ManagedThreadId);

    }
}

私が理解していない部分:

  1. 各スレッドの具体的な制御方法(1つずつまたはすべてのタスクだけを待つのではなく、スレッドごとに)
  2. 各プロセスの実行時間...
4

1 に答える 1

2

これは理想的な仕事のように見えますParallel.ForEach()

パラメーターを使用して同時実行制限を設定し、WebRequest.Timeoutプロパティを使用して、応答を待ちすぎた後に救済することができます。

このようなもの:

Parallel.ForEach(
    urls,
    new ParallelOptions { MaxDegreeOfParallelism = 3 },
    url =>
    {
        try
        {
            var request = WebRequest.Create( url );
            request.Timeout = 10000; // milliseconds
            var response = request.GetResponse();
            // handle response
        }
        catch ( WebException x )
        {
            // timeout or some other problem with the request
        }
        catch ( Exception x )
        {
            // make sure this Action doesn't ever let an exception
            // escape as that would stop the whole ForEach loop
        }
    }
);

への呼び出しParallel.ForEach()は、すべての URL が処理されるまで呼び出しスレッドをブロックします。
ただし、MaxDegreeOfParallelism作業を実行するために最大 スレッドを使用します。

于 2013-03-31T17:35:31.587 に答える