简体   繁体   English

C#5.0中的多线程

[英]multithreading in C# 5.0

I have the following requirements: 我有以下要求:

There are array of urls, which should be downloaded. 有一些网址,应该下载。

  1. Only 3 urls can be in process of downloading simultaneously 只有3个网址可以同时下载
  2. If one (or more) from these 3 urls are completed - need to get next free url from array 如果这3个网址中的一个(或更多)完成 - 需要从数组中获取下一个免费网址
  3. if one (or more) from these 3 urls are not completed during X time - need to cancel this url 如果这三个网址中的一个(或多个)在X时间内未完成 - 需要取消此网址
  4. If array of urls are finished - we wait to complete all current task and only one go our from main method. 如果url数组已经完成 - 我们等待完成所有当前任务,并且只有一个来自main方法。

How to do it on C# 5.0? 如何在C#5.0上做到这一点? I try to do following: 我尝试做以下事情:

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);

    }
}

Which parts I don't understand: 哪些部分我不明白:

  1. How to control each thread concrete (not wait only one-by-one or all tasks, but each thread) 如何控制每个线程具体(不要只等待一个一个或所有任务,但每个线程)
  2. How long each process are executing... 每个进程执行多长时间......

This looks like an ideal job for Parallel.ForEach() 这看起来像Parallel.ForEach()的理想工作

You can set the concurrency limit via a parameter, and then use the WebRequest.Timeout property to bail after waiting too long for a response. 您可以通过参数设置并发限制,然后在等待响应太长时间后使用WebRequest.Timeout属性进行保释。

Something like this: 像这样的东西:

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
        }
    }
);

The call to Parallel.ForEach() will block the calling thread until all the urls have been processed. Parallel.ForEach()的调用将阻塞调用线程,直到所有URL都被处理完毕。
It will, however, use up to MaxDegreeOfParallelism threads to run the work. 但是,它将使用MaxDegreeOfParallelism线程来运行工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM