多线程问题,说它在任务尚未完成之前就完成了

时间:2020-04-21 21:02:26

标签: c# multithreading task

我已经编写了一个空格来处理多个用于硒Web浏览的线程。现在的问题是,例如,如果我输入4个任务和2个线程。该程序说它完成了2个任务后就结束了。

编辑:基本上,我希望程序等待任务完成,而且我还希望如果一个线程完成但另一个线程正在运行并且有任务要做,它将直接启动另一个任务,而不是等待第二个线程完成。

非常感谢您的代码,我们很快将其作为示例进行了展示。

    {
static void Main(string[] args)
    {
        Threads(4, 4);
        Console.WriteLine("Program has finished");
        Console.ReadLine();
    }

    static Random ran = new Random();
    static int loop;
    public static void Threads(int number, int threads)
    {
        for (int i = 0; i < number; i++)
        {
            if (threads == 1)
            {
                generateDriver();
            }
            else if (threads > 1)
            {
            start:
                if (loop < threads)
                {
                    loop++;
                    Thread thread = new Thread(() => generateDriver());
                    thread.Start();

                }
                else 
                {
                    Task.Delay(2000).Wait();
                    goto start;
                }
            }
        }
    }


    public static void test(IWebDriver driver)
    {
        driver.Navigate().GoToUrl("https://google.com/");
        int timer = ran.Next(100, 2000);
        Task.Delay(timer).Wait();
        Console.WriteLine("[" + DateTime.Now.ToString("hh:mm:ss") + "] - " + "Task done.");
        loop--;
        driver.Close();
    }

    public static void generateDriver()
    {
        ChromeOptions options = new ChromeOptions();
        options.AddArguments("--disable-dev-shm-usage");
        options.AddArguments("--disable-extensions");
        options.AddArguments("--disable-gpu");
        options.AddArguments("window-size=1024,768");
        options.AddArguments("--test-type");

        ChromeDriverService service = ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
        service.HideCommandPromptWindow = true;
        service.SuppressInitialDiagnosticInformation = true;

        IWebDriver driver = new ChromeDriver(service, options);
        test(driver);
    }

1 个答案:

答案 0 :(得分:1)

手动跟踪正在运行的线程,等待它们完成并重用已经完成的线程是不容易的。
但是.NET运行时提供了现成的解决方案,您宁愿自己处理它。
要获得所需结果的最简单方法是使用Parallel.For循环并设置MaxDegreeOfParallelism,例如:

public static void Threads(int number, int threads)
{
    Parallel.For(0, number,
                 new ParallelOptions { MaxDegreeOfParallelism = threads },
                 _ => generateDriver());
}

如果您确实想手动执行此操作,则需要使用Thread(或Task)的数组并对其进行迭代,检查它们是否已完成以及是否已将它们替换为新线程。与Parallel.For解决方案相比,这需要更多的代码(并且不太可能表现更好)