Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Нужна помощь с Thread... Добавлено: 02.09.04 03:53  

Автор вопроса:  Oleg K
VB.NET 2003
Помогите кто может. Что-то я совсем заморочился.

Мне надо найти решение, чтобы новый поток не запускался, пока не завершится предыдущий.
Надо обязательно, чтобы потоки выполнялись по очереди - один за другим.

Запускаю последовательно 7 (семь) процессов (задач) из одного диалога, здесь же необходимо выводить показатели затраченного времени на выполнение для каждого и еще один общий. Показатель времени с точностью до милисекунды.

Я пытаюсь использовать:

        autoResetEvent1 = New Threading.AutoResetEvent(False)
        Dim callback As New Threading.WaitOrTimerCallback(AddressOf Calculate)

        Threading.ThreadPool.RegisterWaitForSingleObject(autoResetEvent1, _
                            callback, _
                            Nothing, _
                            Threading.Timeout.Infinite, _
                            False)

Дальше ясно, что Thread ждет autoResetEvent1.Set() - это все работает, но я ни как не могу "допереть", как мне ими управлять...
Подскажите пожалуйста...

Ответить

  Ответы Всего ответов: 6  

Номер ответа: 1
Автор ответа:
 ШевТ



ICQ: 165728420 

Вопросов: 1
Ответов: 96
 Профиль | | #1 Добавлено: 02.09.04 07:58
Dim thr As New Thread(AddressOf A)

Sub Main()

'Управление потоками
A.Start()
A.Abort()

End Sub

Sub A()
' Собственно поток. Обязательно процедура (Sub)!
End Sub

Ответить

Номер ответа: 2
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #2
Добавлено: 02.09.04 14:17
А можно конретнее задачу?

Если просто нужно запустить по очереди потоки t1, t2, t3, чтобы один
стартовал после другого, то используй метод Join:

t1.Start
t1.Join
t2.Start
t2.Join
t3.Start
t3.Join

Метод Join ожидает завершения указанного потока, и только после этого
продолжает выполнение главного потока.

Ответить

Номер ответа: 3
Автор ответа:
 Oleg K



Вопросов: 15
Ответов: 72
 Профиль | | #3 Добавлено: 03.09.04 03:08
1. Есть семь задач, которые выполняют математику на SQL Server...
2. Есть "смопальный" контрол, который по сути является счетчиком времени (свойства Старт, Стоп и Обнулить) и отображает время 00:00:00.00 (до милисекунд)
3. Семь этих контролв-счетчиков лежат на форме.

Дальше необходимые действия
1. Запускаю первый счетчик (1) - он должен будет показать общее время выполнения всех задач
2. Стартую второй счетчик (2) и вместе с ним первую задачу
3. Задача отрабатывает - останавливаю второй счетчик (2)
4. Стартую третий счетчик (3) и вместе с ним вторую задачу
5. Вторая задача отрабатывает - останавливаю третий счетчик (3)
6 ... и т.д. все задачи
7. По окончанию всех хадач останавливаю первый счетчик (1)

Условия:
1. Не известно заранее время выполнения любой из задач.
2. При выполнении всех задач, форма должна быть свободна, чтобы счетчики могли отображать время
3. Выполнение задач обязательно в определенной последовательности одна за другой. По принципу - вторая не стартует, пока не отработает первая и т.д.
4. Все это должно работать в автомате (все задачи беспрерывно одна за другой) по нажатии одной кнопки, типа "Пуск" или "Старт"
5. Моя попытка предложить другой вариант решения, типа - печать результатов в лог файл, а потом его показывать и др. - была отвергнута и требование однозначно, только на форме, отражение результатов в реальном времени. Отсюда и контрол-счетчик.

Мои попытки:

1. Для работы с Thread соорудил класс:


Imports System
Imports System.Threading

Public Class RunProcess

    ;Dim Counter As Object
    ;Dim _state As Boolean = False
    ;Dim _RunComplite As Boolean = False
    'Public state As Boolean
    Private autoResetEvent1 As Threading.AutoResetEvent

    Public Sub New(ByVal obj As Object)
        Counter = obj
        WaitForAutoEvent()
    End Sub

    Public Property autoResetEv() As Boolean
        Get
            Return _state
        End Get
        Set(ByVal Value As Boolean)
            _state = Value
            If _state = True Then
                CType(Counter, Emerald.CounterWTime).Action(Emerald.CounterWTime.StateAction.Runing)
                autoResetEvent1.Set()
            End If
        End Set
    End Property

    Public Property RunComplite() As Boolean
        Get
            Return _RunComplite
        End Get
        Set(ByVal Value As Boolean)
            _RunComplite = Value
            If RunComplite = True Then
                CType(Counter, Emerald.CounterWTime).Action(Emerald.CounterWTime.StateAction.Complited)
            End If
        End Set
    End Property


    Private Sub WaitForAutoEvent()

        autoResetEvent1 = New Threading.AutoResetEvent(False)
        ;Dim callback As New Threading.WaitOrTimerCallback(AddressOf Calculate)

        Threading.ThreadPool.RegisterWaitForSingleObject(autoResetEvent1, _
                            callback, _
                            Nothing, _
                            Threading.Timeout.Infinite, _
                            False)

    End Sub

    Private Sub Calculate(ByVal obj As Object, ByVal TimedOut As Boolean)

        If CType(Counter, Emerald.CounterWTime).Name = "CWT_NoCalc" Then
            Threading.Thread.CurrentThread.Sleep(2000)
            Threading.Thread.CurrentThread.Join()
            RunComplite = True

        ElseIf CType(Counter, Emerald.CounterWTime).Name = "CWT_NoKnow" Then
            Threading.Thread.CurrentThread.Sleep(5000)
            Threading.Thread.CurrentThread.Join()
            RunComplite = True

        ElseIf CType(Counter, Emerald.CounterWTime).Name = "CWT_UTEL" Then
            Threading.Thread.CurrentThread.Sleep(3000)
            Threading.Thread.CurrentThread.Join()
            RunComplite = True

        ElseIf CType(Counter, Emerald.CounterWTime).Name = "CWT_TarifAccount" Then
            Threading.Thread.CurrentThread.Sleep(5500)
            Threading.Thread.CurrentThread.Join()
            RunComplite = True

        ElseIf CType(Counter, Emerald.CounterWTime).Name = "CWT_ResultTarifAccount" Then
            Threading.Thread.CurrentThread.Sleep(4000)
            Threading.Thread.CurrentThread.Join()
            RunComplite = True

        End If

    End Sub

End Class

По кнопке "Выполнить" на форме:

        'Запустим процессы в режиме ожидания
        ;Dim CCWT_NoCalc As New RunProcess(CWT_NoCalc)
        ;Dim CCWT_NoKnow As New RunProcess(CWT_NoKnow)
        ;Dim CCWT_UTEL As New RunProcess(CWT_UTEL)
        ;Dim CCWT_TarifAccount As New RunProcess(CWT_TarifAccount)
        ;Dim CCWT_ResultTarifAccount As New RunProcess(CWT_ResultTarifAccount)

После этого все процессы запущены и находятся (если так можно выразиться) в режиме ожидания.
А ждут они - autoResetEvent1.Set()
И у меня есть возможность дать любому из них (из запущенных Процессов) такую команду через свойство класса autoResetEv.

И при запуске одного потока или всех сразу все это работает, а вот чтобы запустить их по-очереди, один за другим у меня и при этом чтобы лни не пблокировали друг друга или форму у меня не получается...

Ответить

Номер ответа: 4
Автор ответа:
 Oleg K



Вопросов: 15
Ответов: 72
 Профиль | | #4 Добавлено: 03.09.04 03:23
При попытке использовать Join() - счетчик не показывает результат в реальном времени, отображает только конечный результат, после отработки процесса.

Использование Join() отражено в примере класса, который я сюда выложил.

Ответить

Номер ответа: 5
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #5
Добавлено: 03.09.04 09:33
КОд запуска потоков можно также вынести в отдельный поток. Тогда
интерфейс блокироваться не будет.

Ответить

Номер ответа: 6
Автор ответа:
 Oleg K



Вопросов: 15
Ответов: 72
 Профиль | | #6 Добавлено: 03.09.04 22:34
Все.
Спасибо всем.
Я решил свою проблему.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам