Проблема с многопоточностью, говоря, что она закончена до того, как задачи не - PullRequest
0 голосов
/ 22 апреля 2020

Я закодировал void для обработки нескольких потоков для просмотра веб-страниц Selen. Проблема в том, что сейчас, например, если я ввожу 4 задачи и 2 потока. Программа говорит, что она закончила, когда она закончила 2 задачи.

Редактировать: В основном я хочу, чтобы программа ожидала завершения задач, а также я хочу, чтобы, если один поток завершил работу, а другой выполнялся и были задачи чтобы сделать это, он идет непосредственно, чтобы запустить другую задачу, а не ждать 2-го потока, чтобы завершить sh.

Спасибо и извините за код, сделал быстро показать его в качестве примера, как это .

    {
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 Ответ

1 голос
/ 22 апреля 2020

Ручное отслеживание запущенных потоков, ожидание их завершения sh и повторное использование уже законченных потоков не является тривиальным.
Однако среда выполнения. NET предоставляет готовые решения, которые вы предпочитаете обрабатывать. себя.
Самый простой способ достичь желаемого результата - использовать Parallel.For l oop и установить MaxDegreeOfParallelism, например:

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

Если вы действительно хотите сделать это вручную вам нужно будет использовать массивы Thread (или Task) и продолжать итерацию по ним, проверяя, закончили ли они и заменяли ли они новым потоком. Это требует немного больше кода, чем решение Parallel.For (и вряд ли будет работать лучше)

...