Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Thread (многопоточность) / 3 сообщений из 3, страница 1 из 1
02.06.2004, 10:29
    #32544111
vladgrig
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Thread (многопоточность)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Dim ProbaThread As New System.Threading.Thread(AddressOf [MySuperSub])

Private sub Button1_Click...

   ProbaThread.Start()

End Sub

Private Sub MySuperSub

   For...
    ...
    ...
   Next

End Sub

Хочу добавить такое

Код: plaintext
1.
2.
3.
4.
5.
6.
Private sub Button2_Click...

  ProbaThread.Interrupt()


End Sub

Не выходит, потому, что контролы на форме не отвечают и сама форма не отвечает во время выполнения трейда
В книге написано, что нужно перед запуском трейда сделать так
ProbaThread.IsBackground = True
Но, у меня положение дел не поменялось - форма и контролы не доступны
Никто не знает "В чём проблема?"
...
Рейтинг: 0 / 0
04.09.2004, 02:42
    #32680222
lisichanec
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Thread (многопоточность)
Ну вот тебе, как вариант - уверен, можно применить при любой необходимости.
По моей задаче, надо было с одной формы запустить 7 процессов и кроме того для каждого процесса запустить счетчик времени с точностью до милисекунды. Кроме того, один счетчик отображает время для всех процессов. При этом форма свободна.

Счетчиком (у меня) работает самопальный контрол.

Для реализации такой задачи я соорудил вспомагательный класс, в котором при инициализации создается процесс в режиме ожидания "команды для старта".

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
Imports System
Imports System.Threading

Public Class RunProcess

     ' Контрол, который надо запустить  
     ' на выполнение в процессе (Счетчик времени) 
    Dim Counter As Object
     ' В контрол на форме (lblCoProc.Text) буду передавать  
     ' номер (признак, что угодно) для того, чтобы определить  
     ' какой процесс запускать в автомате 
    Dim Leable As Object
     'Переменная для свойства autoResetEv, через это свойство  
     ' с формы будем стартовать процесс (и в моем случае запускать счетчик) 
    Dim _state As Boolean = False
     'Переменная для свойства RunComplite, через это свойство  
     ' с формы будем останавливать процесс (в моем случае останавливать счетчик) 
    Dim _RunComplite As Boolean = False
     ' Сигнал для старта потока 
    Private autoResetEvent1 As Threading.AutoResetEvent


    Public Sub New(ByVal obj As Object, ByVal LbL As Object)
        Counter = obj        ' Получим котрол_счетчик, который надо будет стартовать и останавливать 
        Leable = LbL         ' Получим Лейбу для передачи через нее в форму - Флаг запуска процесса 
        WaitForAutoEvent()   ' Процедура инициализации процесса 
    End Sub


    Public Property autoResetEv() As Boolean
        Get
            Return _state
        End Get
        Set(ByVal Value As Boolean)
            _state = Value
            If _state = True Then
                 ' Emerald.CounterWTime - самопальный контрол (счетчик времени) 
                 ' запускаем отсчет времени 
                Counter.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
                 ' останавливаем счетчик 
                Counter.Action(Emerald.CounterWTime.StateAction.Complited)
            End If
        End Set
    End Property


    Private Sub WaitForAutoEvent()
         ' Создадим автособытие со значением по умолчанию False = Ждем 
        autoResetEvent1 = New Threading.AutoResetEvent(False)
         ' Для возвращенного сообщения от функции Calculate 
        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 )
             ' ЧЕРЕЗ СВОЙСТВО ОСТАНАВЛИВАЮ СЧЕТЧИК ВРЕМЕНИ 
            RunComplite = True
             ' ЧЕРЕЗ ССЫЛКУ ПЕРЕДАЮ В ФОРМУ НОМЕР СЛЕДУЮЩЕГО ПРОЦЕССА ДЛЯ ЗАПУСКА 
            Leable.Text = "2"

        ElseIf CType(Counter, Emerald.CounterWTime).Name = "CWT_NoKnow" Then

            Threading.Thread.CurrentThread.Sleep( 7000 )
            RunComplite = True
            Leable.Text = "3"

        End If

    End Sub

End Class

Для сокращения кода приведу пример для двух процессов.
На форме кроме "всякого не нужного", есть кнопка "Выполнить"
С нее все и начинается.
Еще есть таймер, который постоянно считывает значение lblCoProc.Text выясняя есть ли какой-либо процесс для запуска. Пока значение lblCoProc.Text = "0" - ничего не происходит. Возможно какой-то процесс выполняется или вообще никто еще не стартовал.

Далее часть кода формы, который полностью (в моем случае) отвечает за управление процессами.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
   Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
         'Стартуем Таймер (остановим после завершения всех процессов) 
        Timer1.Start()
         'Запустим общий счетчик времени 
        CWT_Total.Action(Emerald.CounterWTime.StateAction.Runing)
         'Запустим первый процесс, после окончания он запишет в lblCoProc.Text = "2" 
         'и таймер запустит 2 (второй) процесс 
        Dim CCWT_NoCalc As New RunProcess(CWT_NoCalc, lblCoProc)
        CCWT_NoCalc.autoResetEv = True

    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        If lblCoProc.Text = "2" Then
             ' Запустим второй процесс, после окончания он запишет в lblCoProc.Text = "3" 
             'и таймер запустит 3 (третий) процесс 
            CCWT_NoKnowStart()
        ElseIf lblCoProc.Text = "3" Then
            CCWT_UTELStart()
        ElseIf lblCoProc.Text = "4" Then
            CCWT_TarifAccountStart()
        ElseIf lblCoProc.Text = "5" Then
            CCWT_ResultTarifAccountStart()
        ElseIf lblCoProc.Text = "1" Then
            CWT_Total.Action(Emerald.CounterWTime.StateAction.Complited)
        End If

    End Sub

    Private Function CCWT_NoKnowStart()
         ' Обноулим флаг 
        lblCoProc.Text = "0"
         ' Создадим экземпляр класса и вместе с ним новый процесс 
         ' CWT_NoKnow -  имя контрола-счетчика времени 
         ' lblCoProc - имя лейбы для передачи флага 
        Dim CCWT_NoKnow As New RunProcess(CWT_NoKnow, lblCoProc)
         ' СОБСТВЕННО ГОВОРЯ, СЛЕДУЮЩАЯ СТРОКА СТАРТУЕТ ПРОЦЕСС 
        CCWT_NoKnow.autoResetEv = True
    End Function

    Private Function CCWT_UTELStart()
        lblCoProc.Text = "0"
        Dim CCWT_UTEL As New RunProcess(CWT_UTEL, lblCoProc)
        CCWT_UTEL.autoResetEv = True
    End Function

    Private Function CCWT_TarifAccountStart()
        lblCoProc.Text = "0"
        Dim CCWT_TarifAccount As New RunProcess(CWT_TarifAccount, lblCoProc)
        CCWT_TarifAccount.autoResetEv = True
    End Function

    Private Function CCWT_ResultTarifAccountStart()
        lblCoProc.Text = "0"
        Dim CCWT_ResultTarifAccount As New RunProcess(CWT_ResultTarifAccount, lblCoProc)
        CCWT_ResultTarifAccount.autoResetEv = True
    End Function

Ну вот в общем и все. У меня работает прекрасно.
Тебе никто не запрещает перестроить этот код для старта каждого процесса по своей кнопке или другому действию.

Для более глубокого интереса о теории этого всего "гамуза", почитай в MSDN:
AutoResetEvent
ManualResetEvent
Mutex
SyncLock

Для начального ознакомления, очень подойдет статья Андрея Колесова "Многопоточные приложения для .NET"

Всего наилучшего
Oleg K
...
Рейтинг: 0 / 0
04.09.2004, 03:02
    #32680224
lisichanec
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Thread (многопоточность)
Прошу прощения, хочу еще уточнить.

В приведенном мной примере работа настроена таким образом, что второй процесс ждет первый и пока первый процесс не выполнится полностью, второй не стартует и т.д. Все процессы стартуют по очереди, один за другим.

По этому примеру можно организовать старт процессов в любой последовательности или одновременно, или группами, по кнопке - как угодно.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Thread (многопоточность) / 3 сообщений из 3, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]