c# - 执行多个线程的最有效方法

标签 c# multithreading performance threadpool

你可以跳过这部分:

我正在创建一个客户端需要在同一网络上找到服务器的应用程序。

服务器:

public static void StartListening(Int32 端口) {

 TcpListener server = new TcpListener(IP.GetCurrentIP(), port);
 server.Start();

 Thread t = new Thread(new ThreadStart(() =>
   {
     while (true)
       {
         // wait for connection
         TcpClient client = server.AcceptTcpClient();
         if (stopListening)
           {                        
             break;
           }
       }
   }));
 t.IsBackground = true;
 t.Start();

假设服务器正在监听端口 12345

然后客户端:

  • 获取客户端的当前 ip 地址假设它是 192.168.5.88
  • 创建所有可能的 IP 地址列表。服务器 ip 地址可能与客户端的 ip 地址有关,如果它们在同一本地网络上,因此我将列表构造为:

       192.168.5.0
       192.168.5.1
       192.168.5.2
       192.168.5.3
       .....etc
       .....
       192.168.0.88
       192.168.1.88
       192.168.2.88
       192.168.3.88
       ...etc
       192.0.5.88 
       192.1.5.88
       192.2.5.88
       192.3.5.88
       192.4.5.88
       ..... etc
       0.168.5.88
       1.168.5.88
       2.168.5.88
       3.168.5.88
       4.168.5.88
       .... etc       
    

然后我尝试连接每个可能的 ip 和端口 12345。如果一个连接成功,则意味着我找到了服务器的地址。


现在我的问题是:

现在我用两种方式做到了这一点。我只知道有关线程的基础知识,我不知道这是否危险,但它工作得非常快。

        // first way
        foreach (var ip in ListOfIps)
        {               
            new Thread(new ThreadStart(() =>
            {
                TryConnect(ip);
            })).Start();
        }

我认为第二种方式更安全,但需要更多时间:

        // second way
        foreach (var ip in ListOfIps)
        {               
            ThreadPool.QueueUserWorkItem(new WaitCallback(TryConnect), ip);
        }

我必须调用 TryConnect 方法大约 1000 次,每次大约需要 2 秒(我将连接超时设置为 2 秒)。调用它 1000 次的最有效和最安全的方法是什么?


编辑2

以下是使用不同技术的结果:

1) Using threadpool

        ..
        ..
        var now = DateTime.Now;
        foreach (var item in allIps)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), item);
        }

        ThreadPool.QueueUserWorkItem(new WaitCallback(PrintTimeDifference), now);
    }

    static void PrintTimeDifference(object startTime)
    {
        Console.WriteLine("------------------Done!----------------------");
        var s = (DateTime)startTime;
        Console.WriteLine((DateTime.Now-s).Seconds);
    }

enter image description here

完成需要 37 秒

2) Using threads:

        ..
        ..
        var now = DateTime.Now;
        foreach (var item in allIps)
        {
            new Thread(new ThreadStart(() =>
            {
                DoWork(item);

            })).Start();

        }

        ThreadPool.QueueUserWorkItem(new WaitCallback(PrintTimeDifference), now);

enter image description here

完成需要 12 秒

3) Using tasks:

        ..
        ..
        var now = DateTime.Now;
        foreach (var item in allIps)
        {

            var t = Task.Factory.StartNew(() =>

                DoWork(item)
            );                                
        }

        ThreadPool.QueueUserWorkItem(new WaitCallback(PrintTimeDifference), now);
    }

    static void PrintTimeDifference(object startTime)
    {
        Console.WriteLine("------------------Done!----------------------");
        var s = (DateTime)startTime;
        Console.WriteLine((DateTime.Now-s).Seconds);
    }

enter image description here

花了 8 秒!!

最佳答案

在这种情况下,我更喜欢 ThreadPool-Threads 的解决方案,因为创建 1000 个线程是一项繁重的操作(当您考虑每个线程获得的内存时)。 但是自 .NET 4 以来,还有另一个解决方案,类 Task。 任务是可以并行执行的工作负载。您可以像这样定义和运行它们:

var t = Task.Factory.StartNew(() => DoAction());

您不必关心使用的线程数,因为运行时环境会处理它。因此,如果您有可能将您的工作负载拆分成可以并行执行的更小的包,我会使用 Tasks 来完成这项工作。

关于c# - 执行多个线程的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9953856/

相关文章:

multithreading - 在C++ 0x中创建一个在调用线程之前获取互斥量的线程

java - 如何在 Java 中使用多个线程迭代一个集合,其中没有两个线程迭代集合的同一部分?

javascript - 优化巨大的 JSON 响应

performance - 负载测试原始 ssl/tls

c++ - 使用C++ OpenMP和文件io进行并行化。性能问题

c# - 错误 :The name ChromiumWebBrowser does not exist in the namespace "clr-namespace:CefSharp. Wpf;程序集=CefSharp.Wpf

c# - NHibernate 如何确定是插入还是更新记录?

c# - 获取图像中每种颜色的使用百分比

C# Excel 互操作 - 如何测试互操作对象是否仍在工作并执行任务?

c - 从单独的线程调用时 pselect 不返回信号,但在单线程程序中工作正常