none
Как в процедуре дождаться завершения всех потоков ThreadPool? RRS feed

  • Вопрос

  • Начиналось все сложнее, но теперь пришел к "корням". :)

    Код:

        Sub Test()
            Debug.WriteLine("start")
            For i As Integer = 1 To 5
                ThreadPool.QueueUserWorkItem(AddressOf ThreadSub)
            Next
            Debug.WriteLine("stop")
        End Sub
    
        Sub ThreadSub()
            Thread.Sleep(1000)
            Debug.WriteLine(Thread.CurrentThread.ManagedThreadId & " is exit")
        End Sub

    и получаю лог:

    start
    stop
    11 is exit
    11 is exit
    12 is exit
    11 is exit
    13 is exit

    Вопрос - как сделать, чтобы "stop" было последней строкой лога?

    28 января 2013 г. 19:20

Ответы

  • На C# я делаю так:

    static object workerLocker = new object(); static int runningWorkers = 10;
    public static void Go(object instance) { Thread.Sleep(1000); lock (workerLocker) { runningWorkers--; Monitor.Pulse(workerLocker); } } private void Test() { listBox1.Items.Add("Запуск пула..."); for (int i = 0; i < runningWorkers; i++) ThreadPool.QueueUserWorkItem(Go, i); listBox1.Items.Add("Ожидаем завершения работы потоков..."); lock (workerLocker) while (runningWorkers > 0) { Application.DoEvents(); Monitor.Wait(workerLocker); label1.Text = "Осталось потоков: " + runningWorkers.ToString(); } listBox1.Items.Add("Готово!"); }



    • Изменено GT-Volk 29 января 2013 г. 1:46
    • Предложено в качестве ответа GT-Volk 29 января 2013 г. 2:02
    • Помечено в качестве ответа Abolmasov Dmitry 30 января 2013 г. 9:45
    29 января 2013 г. 1:45
  • WaitHandle.WaitAll - смотрите пример.
    • Помечено в качестве ответа Abolmasov Dmitry 30 января 2013 г. 9:45
    29 января 2013 г. 10:51
    Отвечающий

Все ответы

  • ну может быть ThreadPool.QueueUserWorkItem(AddressOf ThreadSub)
    что-то возвращает,
    и это что-то может оказаться IAsyncResult или типа того,
    и там можно их в список собрать,
    а после цикла поставить новый цикл
    тот же foreach по списку этих результов,

    И там может быть есть EndInwoke()
    или что-то типа того

    28 января 2013 г. 19:50
  • ну может быть ThreadPool.QueueUserWorkItem(AddressOf ThreadSub)
    что-то возвращает,
    и это что-то может оказаться IAsyncResult или типа того,
    и там можно их в список собрать,
    а после цикла поставить новый цикл
    тот же foreach по списку этих результов,

    И там может быть есть EndInwoke()
    или что-то типа того

    Слишком много "что-то"... :)

    К сожалению, возвращает этот метод только True (если поток помещен в очередь), либо исключение.

    28 января 2013 г. 20:07
  • На C# я делаю так:

    static object workerLocker = new object(); static int runningWorkers = 10;
    public static void Go(object instance) { Thread.Sleep(1000); lock (workerLocker) { runningWorkers--; Monitor.Pulse(workerLocker); } } private void Test() { listBox1.Items.Add("Запуск пула..."); for (int i = 0; i < runningWorkers; i++) ThreadPool.QueueUserWorkItem(Go, i); listBox1.Items.Add("Ожидаем завершения работы потоков..."); lock (workerLocker) while (runningWorkers > 0) { Application.DoEvents(); Monitor.Wait(workerLocker); label1.Text = "Осталось потоков: " + runningWorkers.ToString(); } listBox1.Items.Add("Готово!"); }



    • Изменено GT-Volk 29 января 2013 г. 1:46
    • Предложено в качестве ответа GT-Volk 29 января 2013 г. 2:02
    • Помечено в качестве ответа Abolmasov Dmitry 30 января 2013 г. 9:45
    29 января 2013 г. 1:45
  • WaitHandle.WaitAll - смотрите пример.
    • Помечено в качестве ответа Abolmasov Dmitry 30 января 2013 г. 9:45
    29 января 2013 г. 10:51
    Отвечающий
  • Пожалуйста, не забывайте отмечать сообщения, решающие вашу проблему (кнопка "Пометить как ответ" под сообщением). Спасибо.


    Для связи [mail]

    30 января 2013 г. 9:45
  • Спасибо. Буду смотреть.

    Думаю, что сказанного достаточно для решения проблемы.

    30 января 2013 г. 11:23