0

我有以下要求:

有一系列网址,应该下载。

  1. 只能同时下载 3 个 url
  2. 如果这 3 个 url 中的一个(或多个)完成 - 需要从数组中获取下一个免费 url
  3. 如果这 3 个 url 中的一个(或多个)在 X 时间内未完成 - 需要取消此 url
  4. 如果 url 数组完成 - 我们等待完成所有当前任务,只有一个来自 main 方法。

如何在 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. 具体如何控制每个线程(不是只等待一个接一个或所有任务,而是每个线程)
  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 回答