【问题标题】:parallel check open port ip from file并行检查文件中打开的端口 ip
【发布时间】:2018-10-29 19:04:15
【问题描述】:

我想检查一组 ip 中的开放端口。我不想按顺序检查标题后面的 ip。但我希望它并行,以便用户确定线程数。 ip个数分为线程:

    private async void button3_Click(object sender, EventArgs e)
    {
        await Task.Run(() => 
        {
            var lines = File.ReadAllLines("ip.txt");
            int cc = (lines.Length) / (int.Parse(thread.Text));
            if (lines.Length % int.Parse(thread.Text) == 0)
            {
                for (int s = 0; s < lines.Length; s = s + cc)
                {
                    Parallel.For(0, 1, a =>
                    {
                        checkopen(s, (s + cc));
                    });
                }
            }
            else
            {
                MessageBox.Show("enter true thread num");
            }
        });
    }

检查开放端口:

    void checkopen(int first,int last)
    {
        int port = Convert.ToInt32(portnum.Text);
        var lines = File.ReadAllLines("ip.txt");
        for (int i = first; i < last; ++i)
        {
            var line = lines[i];
            using (TcpClient tcpClient = new TcpClient())
            {
                    try
                    {
                        tcpClient.Connect(line, port);
                        this.Invoke(new Action(() =>
                        {
                            listBox1.Items.Add(line); // open port
                        }));
                    }
                    catch (Exception)
                    {
                        this.Invoke(new Action(() =>
                        {
                            listBox2.Items.Add(line); //close port
                        }));
                    }
            }
        }
    }

【问题讨论】:

标签: c# task-parallel-library


【解决方案1】:

我每天都看到这个问题,

将 IO 绑定操作放在 Parallel.For 中是没有意义的,它不是为 IO 工作而设计的,或者 async 模式(相信我,这就是你想要的)。

为什么我们需要async await 模式?

因为,它旨在在等待 IO 完成端口或可等待的工作负载时返回线程。

当你像这样在Parallel.For/Parallel.ForEach 中运行 IO 工作时,Task Scheduler 不会主动给你阻塞线程,它使用各种启发式算法来计算你应该有多少线程,并且它对它的看法很模糊。

那么我们应该使用什么呢?

asyncawait 模式

为什么?

因为,我们可以让IO为IO,系统创建IO完成端口,.Net将线程交还给线程池,直到完成端口回调,方法继续。

因此,有很多选择。但首先是await 您正在使用的库的等待async 方法。

您可以从这里创建任务列表并使用诸如可等待的SemiphoreSlim 来限制并发和WhenAll

或者您可以使用 TPL Dataflow 中的 ActionBlock 之类的东西,它旨在处理 CPU 和 IO 绑定的工作负载。

现实世界的好处不可低估。您的Parallel.For 方法只会运行少量线程并阻止它们。一个可以同时运行 100 次的异步版本

数据流示例

You can get the Nuget here

public async Task DoWorkLoads(List<WorkLoad> workloads)
{
   var options = new ExecutionDataflowBlockOptions
                     {
                        // add pepper and salt to taste
                        MaxDegreeOfParallelism = 100,
                        EnsureOrdered = false
                     };

   // create an action block
   var block = new ActionBlock<WorkLoad>(MyMethodAsync, options);

   // Queue them up
   foreach (var workLoad in workloads)
      block.Post(workLoad );

   // wait for them to finish
   block.Complete();
   await block.Completion;

}

...

// Notice we are using the async / await pattern
public async Task MyMethodAsync(WorkLoad workLoad)
{

    try
    {
        Console.WriteLine("Doing some IO work async);
        await DoIoWorkAsync;
    }
    catch (Exception)
    {
        // probably best to add some error checking some how
    }
}

【讨论】:

  • 谢谢大哥..但是我想查看组ip中开放的端口。至少时间。所以我想使用并行性。还有其他方法吗?
  • @MohammadShaheen 更新了一个异步感知 TPL 数据流示例,您所要做的就是添加您的异步代码。但是请注意,如果要存储任何结果,则需要使用线程安全集合
猜你喜欢
  • 2011-08-18
  • 2012-08-03
  • 2023-04-07
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
  • 2019-02-09
  • 2022-01-26
相关资源
最近更新 更多