Thrower 发表于 2021-8-30 13:00

大佬们C#task如何限制最大并行Task数量呢?

本帖最后由 Thrower 于 2021-8-30 13:02 编辑

最近在写一个爆破程序,具体的逻辑就是把用户名和密码字典里面的所有行赋值给两个数组,创建一个task类的list然后通过for循环嵌套来添加执行task任务。但是我遇到了一个很难办的问题,就是当字典里面的行数过多,因为一般都是字典越大越好,字典大了以后呢建立的Task就变得越来越多,就会导致内存占用越来越多最后程序无响应退出。
有问题的具体的代码如下:
currentrequestId++;
            int a = currentrequestId;
            RequestIds.Add(currentrequestId, true);
            List<Task> TaskList = new List<Task>();
            for (int i = 0; i < users.Length; i++)
            {
                int l = i;
                for (int y = 0; y < passwords.Length; y++)
                {
                  int Y = y;
                  TaskList.Add(Task.Factory.StartNew(() =>
                  {
                        if (RequestIds)
                        {
                            bool result = FTPRequest(host, users, passwords);
                            if (result)
                            {
                              BeginInvoke(new Action(() =>
                              {
                                    if (RequestIds)
                                    {
                                        if(checkBox1.Checked)
                                        {
                                          RequestIds = false;
                                          richTextBox3.Text += "爆破成功!用户名:" + users + " 密码:" + passwords + "\r";
                                          button3.Text = "开始爆破";
                                          label2.Text = "";
                                          richTextBox3.Text += "爆破结束!";
                                          textBox1.Enabled = true;
                                          button1.Enabled = true;
                                          button2.Enabled = true;
                                          radioButton1.Enabled = true;
                                          radioButton2.Enabled = true;
                                          radioButton3.Enabled = true;
                                          checkBox1.Enabled = true;
                                          MessageBox.Show("爆破结束!用户名:" + users + "密码:" + passwords, "提示");
                                        }
                                        else
                                        {
                                          richTextBox3.Text += "爆破成功!用户名:" + users + " 密码:" + passwords + "\r";
                                        }                                       
                                    }
                              }));
                            }
                            else
                            {
                              BeginInvoke(new Action(() =>
                              {
                                    if (RequestIds)
                                    {
                                        richTextBox3.Text += "正在爆破!当前用户名:" + users + " 当前密码:" + passwords + "\r";
                                    }
                              }));
                            }
                        }
                        else
                        {
                            return;
                        }
                  }));
                }
整个程序的源码在一个Github仓库:https://github.com/7hr0wer/SuperBuster
所以我现在的思路就是像ThreadPool类的SetMaxThread一样设置一个最大的Task并行数量,我也通过搜索引擎查了,网上大多都是用
LimitedConcurrencyLevelTaskScheduler实现的限制,
我按照自己的理解,也就是说
TaskFactory fac = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(5));里面的这个5是是设置的最大Task并发数量,按照代码实例重写了,可是仍然没有任何变化。
我不知道是不是我的理解有误!所以请问有没有大佬知道Task如何设置最大并行Task数量?如果我的理解有误,能否指出我的错误并且纠正呢?
如果大佬们能给出有代码注释的Demo那就更好了!谢谢!
TaskFactory fac = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(5));

Light紫星 发表于 2021-8-30 15:41

ThreadPool.SetMinThreads(1000, 1000);
ThreadPool.SetMaxThreads(5000, 5000);
这两行是设置最大和最小并发数的

Thrower 发表于 2021-8-30 15:49

Light紫星 发表于 2021-8-30 15:41
ThreadPool.SetMinThreads(1000, 1000);
ThreadPool.SetMaxThreads(5000, 5000);
这两行是设置最大和最小 ...

但是那个是线程池呀,我用的是task类,我是想实现这样的设置。

lene 发表于 2021-8-30 16:05

TaskFactory fac = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(num)); 是有效的哦,检查下代码吧

Thrower 发表于 2021-8-30 17:13

lene 发表于 2021-8-30 16:05
TaskFactory fac = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(num)); 是有效的哦,检查下 ...

嗯嗯,我现在好像发现问题了,因为字典过大导致创建的task过多,所以导致使用了调度器以后虽然task在等待不执行但因为task过多占用内存过大所以卡退。是不是只要我分批创建task就行了呢?

huiye123 发表于 2021-8-31 10:01

哥啊。就不是你这样用得。 是你直接建立几个线程,然后线程里面直接while(true) 直到把这个字典push完成。然后就结束,不是一直新建任务。,任务调度,切换线程是需要时间的。而且还是时间片轮询。

Thrower 发表于 2021-8-31 12:47

huiye123 发表于 2021-8-31 10:01
哥啊。就不是你这样用得。 是你直接建立几个线程,然后线程里面直接while(true) 直到把这个字典push完成 ...

这是根据用户名和密码字典的账号组合创建task任务的,每个task分配一个组合,速度会快很多。

huiye123 发表于 2021-9-3 10:14

那你最后面解决了没? 不是很能理解你的逻辑。或者说我的level 不够,所以想问问最后你是怎么解决的

Thrower 发表于 2021-9-3 20:02

huiye123 发表于 2021-9-3 10:14
那你最后面解决了没? 不是很能理解你的逻辑。或者说我的level 不够,所以想问问最后你是怎么解决的

最后我是通过限制task并发数量解决的。通过list.count判断task数量进行限制,比如大于两千那么等待任意一个执行完再添加。task.waitany

huiye123 发表于 2021-9-6 09:55

好吧,能解决就是好事。
页: [1] 2
查看完整版本: 大佬们C#task如何限制最大并行Task数量呢?