Модераторы: diadiavova, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Многопоточные приложения, и элементы формы 
V
    Опции темы
Pankon
Дата 7.6.2006, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 739
Регистрация: 2.6.2005

Репутация: нет
Всего: 5



Такой код
Код

Imports System.Threading
Public Class frmTestThread
    Dim Thread1 As Thread
    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        Thread1 = New Thread(AddressOf ThreadVBNET)
        Thread1.Start()
    End Sub
    Private Sub ThreadVBNET()
        Do While True
            txtView.Text = txtView.Text + Now & vbCrLf
        Loop
    End Sub
    Private Sub btnEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnd.Click
        Thread1.Abort()
    End Sub
End Class
дает ошибку на  txtView.Text = txtView.Text + Now & vbCrLf. (процесс не правильно обращается к элементу формы).
А как правильно переписать этот код smile  
PM MAIL   Вверх
ivashkanet
Дата 7.6.2006, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 5
Всего: 149



Нужно на форме написать метод "Запись в txtView" и обратиться к нему через
Код

<Указатель/переменная на форму>.invoke(<Делегат на созданный метод>)

  

Это сообщение отредактировал(а) ivashkanet - 7.6.2006, 17:44
PM MAIL WWW ICQ   Вверх
Exception
Дата 7.6.2006, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 18
Всего: 186



Многие элементы WinForms не являются безопасными по отношению к потокам. Поэтому обращаться к ним можно только из того потока, в котором они были созданы. Если нужно обратиться из другого потока, проверяй свойство InvokeRequired и вызывай метод Invoke с передачей делегата на метод, который нужно выполнить - контрол его вызовет сам:

Код

    Private Sub ThreadVBNET()
        If txtView.InvokeRequired Then
            txtView.Invoke(AddressOf DoSomeActions)
        Else
            DoSomeActions()
        End If
    End Sub

    Private Sub DoSomeActions()
        Do While True
            txtView.Text = txtView.Text + Now & ControlChars.CrLf
        Loop
    End Sub


Впрочем, разумнее для этих целей воспользоваться компонентом BackgroundWorker, который инкапсулирует эту функциональность.

Добавлено @ 17:47 
FAQed.

http://vingrad.ru/NET-VBNET-003045

Добавлено @ 17:49 
 
PM   Вверх
Pankon
Дата 7.6.2006, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 739
Регистрация: 2.6.2005

Репутация: нет
Всего: 5



Exception, sorry 
Цитата(Exception @  7.6.2006,  17:37 Найти цитируемый пост)
txtView.Invoke(AddressOf DoSomeActions)
 здесь система говорит, что не может конвертировать AddressOf  в System.Delegate  smile   

Это сообщение отредактировал(а) Pankon - 7.6.2006, 17:55
PM MAIL   Вверх
Pankon
Дата 7.6.2006, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 739
Регистрация: 2.6.2005

Репутация: нет
Всего: 5



Заработало следующее:
Код

Imports System.Threading
Public Class frmTestThread
    Delegate Sub myMethodDelegate()
    Dim Thread1 As Thread
    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        Dim bThreadStart As New ThreadStart(AddressOf ThreadVBNET)
        Thread1 = New Thread(bThreadStart)
        Thread1.Start()
    End Sub
    Private Sub ThreadVBNET()
        Dim myD1 As New myMethodDelegate(AddressOf DoSomeActions)
        Do While True
            If txtView.InvokeRequired Then
                txtView.Invoke(myD1)
            Else
                DoSomeActions()
            End If
        Loop
    End Sub
    Private Sub DoSomeActions()
        txtView.Text = Now & ControlChars.CrLf
    End Sub
    Private Sub btnEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnd.Click
        Thread1.Abort()
        txtView.Text = txtView.Text & " END"
    End Sub
End Class

Всем спасибо. 
PM MAIL   Вверх
Exception
Дата 7.6.2006, 20:59 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 18
Всего: 186



В таком случае правильнее воспользоваться специально для этого предназначенным делегатом MethodInvoker:

Код

    Private Sub ThreadVBNET()
        If txtView.InvokeRequired Then
            txtView.Invoke(New MethodInvoker(AddressOf DoSomeActions))
        Else
            DoSomeActions()
        End If
    End Sub

    Private Sub DoSomeActions()
        Do While True
            txtView.Text = txtView.Text + Now & ControlChars.CrLf
        Loop
    End Sub
 
PM   Вверх
Pankon
Дата 8.6.2006, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 739
Регистрация: 2.6.2005

Репутация: нет
Всего: 5



Exception,  спасибо за участие smile

Я тут внимательно почитал про InvokeRequired :
Цитата
Возвращает значение, показывающее, следует ли вызывающему оператору обращаться к методу invoke во время вызовов метода из элемента управления, так как вызывающий оператор находится не в том потоке в котором был создан элемент управления.
и 
Цитата
Значение true, если Handle элемента управления был создан не в вызывающем потокеа в другом (показывает, что необходимо вызвать элемент управления через метод invoke); в противном случае — false.

Я вызываю метод элемента из другого потока и проверка(If txtView.InvokeRequired Then), что элемент из другого потока - лишняя(если, конечно, не вызывать метод ThreadVBNET() из главного потока smile).
И я так понял, что конструкцию txtView.Invoke(New MethodInvoker(AddressOf DoSomeActions)) (см. Exception) нужно(желательно) вызывать для каждого обращения к методам елемента из другого потока.(Exception твой последний вариант так "грузит" приложение, что оно не на что не реагируетsmile Я предполагаю, что цыкл обращений к методам элемента управления, вызванный из Invoke "занимает" элемент управления и он становится не доступен из других(в том числе и из главного) потоков. (Не помогает даже sleep и понижение Priority.)
Код
txtView.Invoke(New MethodInvoker(AddressOf DoSomeActions))
....
     Private Sub DoSomeActions()
        Do While True
            txtView.Text = txtView.Text + Now & ControlChars.CrLf
        Loop
    End Sub)

Вот то, что, по моему, оптимально должно работать (по крайней мере у меня работаетsmile
Код

     Dim flag1 As Boolean
    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart1.Click
        Dim bThreadStart As New ThreadStart(AddressOf ThreadVBNET)
        Thread1 = New Thread(bThreadStart)
        Thread1.Name = "My Thread1"
        Thread1.Priority = ThreadPriority.Lowest
        flag1  = True
        Thread1.Start()
    End Sub
    Private Sub ThreadVBNET()
        'If txtView.InvokeRequired Then
        Do While flag1
            txtView.Invoke(New MethodInvoker(AddressOf DoSomeActions))
            Thread.Sleep(150)
        Loop
        'Else
        'DoSomeActions()
        'End If
    End Sub
    Private Sub DoSomeActions()
        txtView.Text = Now
    End Sub
    Private Sub btnEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnd1.Click
        flag1 = False
    End Sub

Если кто-то найдет не точности в рассуждении или в коде - милости просим, поделитесь.. Уж очень хочется разобраться, а не просто примеры из книжки использовать, а так же знать и понимать, что пишу.......  smile 
  

Это сообщение отредактировал(а) Pankon - 8.6.2006, 10:52
PM MAIL   Вверх
Exception
Дата 8.6.2006, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 18
Всего: 186



Меня терзает мысль, что всё заработает, если в тело цикла вставить

Код

Application.DoEvents()


Добавлено @ 16:58 
Я про это:

Цитата(Pankon @  8.6.2006,  11:52 Найти цитируемый пост)
твой последний вариант так "грузит" приложение, что оно не на что не реагирует

 

Это сообщение отредактировал(а) Exception - 8.6.2006, 16:55
PM   Вверх
Pankon
Дата 8.6.2006, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 739
Регистрация: 2.6.2005

Репутация: нет
Всего: 5



Цитата(Exception @  8.6.2006,  16:54 Найти цитируемый пост)
Application.DoEvents()

Проложению немного полегчало  smile 

Тогда вопрос про совместный доступ: 
А если во время работы этого потока, другой поток захочет обратиться к этому элементу. Что тогда? ... И почему?... smile  
PM MAIL   Вверх
HalkaR
Дата 8.6.2006, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пуфыстый назгул
****


Профиль
Группа: Экс. модератор
Сообщений: 2132
Регистрация: 8.12.2002
Где: В Москве

Репутация: нет
Всего: 42



System.Threading.Monitor.Enter() и System.Threading.Monitor.Exit() должны помочь.

Добавлено @ 18:05 
Код

System.Threading.Monitor.Enter(txtView)
вызов
System.Threading.Monitor.Exit(txtView)
 
PM MAIL   Вверх
ivashkanet
Дата 8.6.2006, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 5
Всего: 149



Цитата(Pankon @  8.6.2006,  17:58 Найти цитируемый пост)
Тогда вопрос про совместный доступ: 

Тут про совместную работу хорошо написано:
Синхронизация потоков по .NETовски


 
PM MAIL WWW ICQ   Вверх
Exception
Дата 10.6.2006, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 18
Всего: 186



Цитата(ivashkanet @  8.6.2006,  19:27 Найти цитируемый пост)
Тут про совместную работу хорошо написано:
Синхронизация потоков по .NETовски


Угу, респект Коту smile 
PM   Вверх
arilou
Дата 14.6.2006, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 7
Всего: 61



Цитата(HalkaR @  8.6.2006,  18:03 Найти цитируемый пост)
System.Threading.Monitor.Enter() и System.Threading.Monitor.Exit() должны помочь.

Вместо этого лучше юзать

Код

SyncLock
' ....
End SyncLock
  

Это сообщение отредактировал(а) arilou - 14.6.2006, 22:47


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума VB .NET
diadiavova
  • Прежде чем задать вопрос, воспользуйтесь поиском: возможно Ваш вопрос уже обсуждался и на него был получен ответ.
  • Если такой же вопрос не найден, не стоит задавать свой вопрос в любую тему, создайте новую.
  • Заголовок темы должен отображать ее суть.
  • Содержание поста должно описывать проблему понятно, но в то же время, по возможности, лаконично. Сначала следует описать суть вопроса, потом можно привести пример кода, не вынуждайте других участников угадывать в чем Ваша проблема - телепатов здесь нет.
  • Будьте взаимно вежливы и дружелюбны.
  • При оформлении сообщений используйте форматирование, примеры кода заключайте в теги [CODE=vbnet][/CODE].
  • Также ознакомьтесь с общими правилами, действующими на всем форуме.
  • Если вопрос решен, не забывайте помечать тему решенной(вверху темы есть ссылка). Кроме того, если Вы хотите отблагодарить участников, оказавших помощь в решении, можно повысить им репутацию, в случае, если у Вас менее 100 сообщений в форуме и функция изменения репутации Вам недоступна, можете написать сюда.
  • Общие вопросы по программированию на платформе .NET обсуждаются здесь.
  • Литература по VB .NET обсуждается здесь.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, diadiavova.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | VB .NET | Следующая тема »


 




[ Время генерации скрипта: 0.1270 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.