【问题标题】:multithreading in C# 5.0C# 5.0 中的多线程
【发布时间】:2013-04-01 01:35:31
【问题描述】:

我有以下要求:

有url数组,应该下载。

  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. 每个进程执行多长时间...

【问题讨论】:

    标签: c# multithreading c#-5.0


    【解决方案1】:

    这看起来是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 个线程来运行该工作。

    【讨论】:

      猜你喜欢
      • 2012-11-01
      • 1970-01-01
      • 2010-12-14
      • 1970-01-01
      • 2011-06-02
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多