Выполнение процедуры класса в отдельном потоке

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 11.09.2012 (Вт) 12:40

Здравствуйте. Начал изучать многопоточность на примерах с MSDN:
Код: Выделить всё
Public Class Form1
    Inherits Form
    Delegate Sub SetTextCallback(ByVal [text] As String)
    Private demoThread As Thread = Nothing
    Sub SetText(ByVal [text] As String)
        ' InvokeRequired required compares the thread ID of the
        ' calling thread to the thread ID of the creating thread.
        ' If these threads are different, it returns true.
        If Me.Label1.InvokeRequired Then
            Dim d As New SetTextCallback(AddressOf SetText)
            Me.Invoke(d, New Object() {[text]})
        Else
            Me.Label1.Text = text
        End If
    End Sub
    Private Sub ThreadProcSafe()
        Dim i As Integer = 0
        Do While i < 10
            i = i + 1
            Me.SetText(i)
            Thread.Sleep(100)
        Loop
    End Sub

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.demoThread = New Thread( _
        New ThreadStart(AddressOf ThreadProcSafe))
        Me.demoThread.Start()
    End Sub
End Class

Все отлично работает, но при выполнении той же процедуры но из отдельного класса возникают непонятности: на главной форме Label остается без изменений, IDE никаких ошибок не выдает при этом. В чем причина?
Код: Выделить всё
Public Class Form1
    ' Inherits Form
    Delegate Sub SetTextCallback(ByVal [text] As String)
    Private demoThread As Thread = New Thread( _
        New ThreadStart(AddressOf DemoKlass.ThreadProcSave))
    'Private WithEvents backgroundWorker1 As BackgroundWorker
    Sub SetText(ByVal [text] As String)
        ' InvokeRequired required compares the thread ID of the
        ' calling thread to the thread ID of the creating thread.
        ' If these threads are different, it returns true.
        If Me.Label1.InvokeRequired Then
            Dim d As New SetTextCallback(AddressOf SetText)
            Me.Invoke(d, New Object() {[text]})
        Else
            Me.Label1.Text = text
        End If
    End Sub
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.demoThread.Start()
    End Sub
    Public Class DemoKlass
        Public Shared Sub ThreadProcSave()
            Dim i As Integer = 0
            Do While i < 10
                i = i + 1
                Form1.SetText(i)
                Thread.Sleep(100)
            Loop
        End Sub
    End Class
End Class

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 11.09.2012 (Вт) 13:35

Dimitriy писал(а):Form1.SetText(i)

Потому что не надо так к форме обращаться...
Либо передавай форму в класс, либо иди через My.

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 12.09.2012 (Ср) 4:10

Да пробовал и через My. Тут еще странность - если из класса делать проверку
Код: Выделить всё
Form1.Label1.InvokeRequired

всегда возвращает False, хотя потоки точно разные.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 12.09.2012 (Ср) 7:36

Ещё раз. Form1 - это имя класса, не объекта. Такое обращение не имеет того смысла, который был в VB6. Обращение через My.Forms.Form1 - это уже обращение к переменной, однако, если форма не существует, то она будет создана. My - это вообще попытка предоставить эмитацию некоторых возможностей VB6. Я не знаю, как оно взаимодействует с потоками. Вполне возможно, что каждый поток у тебя создаёт отдельную форму, а может и нет. Правильнее передать ссылку на форму в класс и с ней работать. Кстати, в шарпе это было бы единственно-возможным вариантом.

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 12.09.2012 (Ср) 10:16

Передача ссылки на форму в класс это?
Код: Выделить всё
Imports НазваниеПроекта.Form1

Или я чего то путаю?

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 12.09.2012 (Ср) 10:24

Вообще странно - про многопоточность в интернете много написано, а именно про выполнение собственных классов в отдельных потоках - почти ничего.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Выполнение процедуры класса в отдельном потоке

Сообщение FireFenix » 12.09.2012 (Ср) 18:36

Если вызов гарантированно идёт из потока, то InvokeRequired проверять не нужно

Dimitriy писал(а):Вообще странно - про многопоточность в интернете много написано, а именно про выполнение собственных классов в отдельных потоках - почти ничего.

Для этого нужно проявить разум и понять как всё работает, ибо работает по одинаковому принципу во всех классах
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 12.09.2012 (Ср) 19:38

Dimitriy писал(а):Передача ссылки на форму в класс это?
Код: Выделить всё
Imports НазваниеПроекта.Form1

Или я чего то путаю?

Путаешь, причём всё.

Код: Выделить всё
Imports System.Threading

Public Class Form1
Inherits Form

  Private WithEvents Lbl As New Label() With {.Text = "It's just a label", .Left = 8, .Width = 100, .Visible = True}
  Private WithEvents Btn As New Button() With {.Text = "Do it!", .Left = 8, .Top = 36, .Width = 100, .Visible = True}

  Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.Controls.Add(Lbl)
    Me.Controls.Add(Btn)
  End Sub

  Public Sub DoIt(ByVal Text As String)
    If Me.Lbl.InvokeRequired Then
      Me.Invoke(Sub(Str As String) DoIt(Str), {Text})
    Else
      Me.Lbl.Text = Text
    End If
  End Sub

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Btn.Click
    Call (New Thread(Sub() Call (New DemoClass() With {.Frm = Me}).DoSmth())).Start()
  End Sub

End Class

Public Class DemoClass
  Public Property Frm As Form1

  Public Sub DoSmth()
    For Q As Integer = 0 To 64
      Frm.DoIt(Q)
      Thread.Sleep(100)
    Next Q

    Frm.DoIt(Now())
  End Sub
End Class

Код: Выделить всё
c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\vbc.exe /target:winexe /optimize+ /debug- /out:Invoker.exe /imports:System.Windows.Forms /main:Form1 *.vb
start Invoker.exe

PS: DemoKlass - издеваешься что ли? Я 15 минут думал, почему код не компилируется!

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 13.09.2012 (Чт) 4:16

Так это же название класса который я сам создал, название может быть любым.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 13.09.2012 (Чт) 7:34

Dimitriy писал(а):Так это же название класса который я сам создал, название может быть любым.

Да, только когда я написал вызов через C (а мне и в голову не приходило, что там может стоять K), компилироваться оно не стало...

Qwertiy писал(а):Me.Invoke(Sub(Str As String) DoIt(Str), {Text})

Можно так:
Код: Выделить всё
Me.Invoke(Sub() DoIt(Text), {})

Так ты разобрался или нет?

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 14.09.2012 (Пт) 4:23

Так нельзя - будет ошибка типа такой: Обращение к элементу до создания его дескриптора. Я в самом начале так пробовал.
Кнопки и формы я через конструктор на форму добавляю, поэтому код
Код: Выделить всё
Private WithEvents Lbl As New Label() With {.Text = "It's just a label", .Left = 8, .Width = 100, .Visible = True}
  Private WithEvents Btn As New Button() With {.Text = "Do it!", .Left = 8, .Top = 36, .Width = 100, .Visible = True}

  Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.Controls.Add(Lbl)
    Me.Controls.Add(Btn)

не нужен.

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 14.09.2012 (Пт) 4:25

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

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.09.2012 (Пт) 6:40

Dimitriy писал(а):Так нельзя - будет ошибка типа такой: Обращение к элементу до создания его дескриптора. Я в самом начале так пробовал.

Не понял, как именно нельзя? Скомпилируй любой вариант и запусти - всё работает!

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 14.09.2012 (Пт) 9:20

Все работает если не создавать класс, а если попробовать из класса то будет:
"Невозможно вызвать Invoke или BeginInvoke для элемента управления до завершения создания дескриптора окна."

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.09.2012 (Пт) 13:11

Ты какую-то ерунду пишешь. Или тут, или в коде, или и там и там.
Мой код работает в обоих варианнатх. Что тебя не устраивает?
Какой код у тебя не работает, никто кроме тебя вообще не знает.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Выполнение процедуры класса в отдельном потоке

Сообщение FireFenix » 14.09.2012 (Пт) 13:21

Dimitriy писал(а):Все работает если не создавать класс, а если попробовать из класса то будет:
"Невозможно вызвать Invoke или BeginInvoke для элемента управления до завершения создания дескриптора окна."

Ну прояви же ты интеллект. Почитай книжку/мануал и сам поковыряй.

Что такое многозадачность? Процессор в реалтайме не обрабатывает сразу все потоки, а только в один момент времени только один поток - это выделение кванта времени потоку и переключение на выполнение другого потока, тем самым там за секунду происходит скажем отработка 4х потоков по 250 миллисекунд.

В твоей ситуации изначально есть некоторые поток с формой который создаётся с процессом. Ты создаёшь второй поток.
Когда каждый поток использует свои данные то всё ок. Но когда поток пытается обратится к ресурсам другого потока, то происходит исключение.
Первая проблема - это найти способ достучаться для данных в другом потоке.
Вторая проблема - механизм предотвращающий порчу данных одного потока действиями из вне. Чтобы этого не случалось, то используется Invoke, т.е. при вызове происходит синхронизация потоков и передача данных.

У тебя очевидно проблема в понимании процесса работы и осознании того как это всё работает.

Более того, тебе дали рабочий пример с вызовом, откуда проблемы?
111.PNG

112.PNG

1113.PNG
Последний раз редактировалось FireFenix 14.09.2012 (Пт) 13:22, всего редактировалось 1 раз.
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.09.2012 (Пт) 13:21

Да, если ты имел в виду вызов Invoke для формы из класса, то и это работает (оба варианта):
Код: Выделить всё
Imports System.Threading

Public Class Form1
Inherits Form

  Public WithEvents Lbl As New Label() With {.Text = "It's just a label", .Left = 8, .Width = 100, .Visible = True}
  Private WithEvents Btn As New Button() With {.Text = "Do it!", .Left = 8, .Top = 36, .Width = 100, .Visible = True}

  Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.Controls.Add(Lbl)
    Me.Controls.Add(Btn)
  End Sub

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Btn.Click
    Call (New Thread(Sub() Call (New DemoClass() With {.Frm = Me}).DoInvoke())).Start()
  End Sub

End Class

Public Class DemoClass
  Public Property Frm As Form1
 
  Public Sub DoInvoke()
    For Q As Integer = 0 To 64
      'Frm.Invoke((Function(Str As String) Sub() Frm.Lbl.Text = Str)(Q), {})
      Frm.Invoke(Sub(Str As String) Frm.Lbl.Text = Str, {Q.ToString()})
      Thread.Sleep(100)
    Next Q

    Frm.Invoke(Sub() Frm.Lbl.Text = Now(), {})
  End Sub
End Class

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 15.09.2012 (Сб) 18:13

Спасибо тебе за помощь. Моя проблема была в том что я не прописывал как ты в классе
Код: Выделить всё
Public Property Frm As Form1

ну и соответсвтенно на кнопке не было прописано как у тебя
Код: Выделить всё
DemoClass() With {.Frm = Me}

Спасибо за проявленное терпение, видимо впредь нужно матчасть более внимательно изучать...

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 15.09.2012 (Сб) 18:42

Qwertiy писал(а):
Dimitriy писал(а):Передача ссылки на форму в класс это?
Код: Выделить всё
Imports НазваниеПроекта.Form1

Или я чего то путаю?

Путаешь, причём всё.

Код: Выделить всё
Imports System.Threading

Public Class Form1
Inherits Form

  Private WithEvents Lbl As New Label() With {.Text = "It's just a label", .Left = 8, .Width = 100, .Visible = True}
  Private WithEvents Btn As New Button() With {.Text = "Do it!", .Left = 8, .Top = 36, .Width = 100, .Visible = True}

  Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.Controls.Add(Lbl)
    Me.Controls.Add(Btn)
  End Sub

  Public Sub DoIt(ByVal Text As String)
    If Me.Lbl.InvokeRequired Then
      Me.Invoke(Sub(Str As String) DoIt(Str), {Text})
    Else
      Me.Lbl.Text = Text
    End If
  End Sub

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Btn.Click
    Call (New Thread(Sub() Call (New DemoClass() With {.Frm = Me}).DoSmth())).Start()
  End Sub

End Class

Public Class DemoClass
  Public Property Frm As Form1

  Public Sub DoSmth()
    For Q As Integer = 0 To 64
      Frm.DoIt(Q)
      Thread.Sleep(100)
    Next Q

    Frm.DoIt(Now())
  End Sub
End Class

Код: Выделить всё
c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\vbc.exe /target:winexe /optimize+ /debug- /out:Invoker.exe /imports:System.Windows.Forms /main:Form1 *.vb
start Invoker.exe

PS: DemoKlass - издеваешься что ли? Я 15 минут думал, почему код не компилируется!

Я на данный форум с работы выходил, у на прокси сервере некоторые фильтры включены и я не полностью твой пример кода видел (не отображается полоса прокрутки на работе) сегодня с домашнего компа форум открыл. Мда, получается что я с 12 числа не видя полностью твой пример кода грел тебе мозг почем зря... Приношу свои извинения.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 15.09.2012 (Сб) 21:44

Dimitriy писал(а):Я на данный форум с работы выходил, у на прокси сервере некоторые фильтры включены и я не полностью твой пример кода видел (не отображается полоса прокрутки на работе) сегодня с домашнего компа форум открыл. Мда, получается что я с 12 числа не видя полностью твой пример кода грел тебе мозг почем зря... Приношу свои извинения.

Ну и при чём тут прокси? Ты действительно думаешь, что прокси может вырезать кусок из
Код: Выделить всё
<div class="content"><blockquote><div><cite>Dimitriy писал(а):</cite>Передача ссылки на форму в класс это?<br /><dl class="codebox"><dt>Код: <a href="#" onclick="selectCode(this); return false;">Выделить всё</a></dt><dd><code>Imports НазваниеПроекта.Form1</code></dd></dl><br />Или я чего то путаю?</div></blockquote><br />Путаешь, причём всё.<br /><br /><dl class="codebox"><dt>Код: <a href="#" onclick="selectCode(this); return false;">Выделить всё</a></dt><dd><code>Imports System.Threading<br /><br />Public Class Form1<br />Inherits Form<br /><br />&nbsp; Private WithEvents Lbl As New Label() With {.Text = &quot;It's just a label&quot;, .Left = 8, .Width = 100, .Visible = True}<br />&nbsp; Private WithEvents Btn As New Button() With {.Text = &quot;Do it!&quot;, .Left = 8, .Top = 36, .Width = 100, .Visible = True}<br /><br />&nbsp; Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load<br />&nbsp; &nbsp; Me.Controls.Add(Lbl)<br />&nbsp; &nbsp; Me.Controls.Add(Btn)<br />&nbsp; End Sub<br /><br />&nbsp; Public Sub DoIt(ByVal Text As String)<br />&nbsp; &nbsp; If Me.Lbl.InvokeRequired Then<br />&nbsp; &nbsp; &nbsp; Me.Invoke(Sub(Str As String) DoIt(Str), {Text})<br />&nbsp; &nbsp; Else<br />&nbsp; &nbsp; &nbsp; Me.Lbl.Text = Text<br />&nbsp; &nbsp; End If<br />&nbsp; End Sub<br /><br />&nbsp; Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Btn.Click<br />&nbsp; &nbsp; Call (New Thread(Sub() Call (New DemoClass() With {.Frm = Me}).DoSmth())).Start()<br />&nbsp; End Sub<br /><br />End Class<br /><br />Public Class DemoClass<br />&nbsp; Public Property Frm As Form1<br /><br />&nbsp; Public Sub DoSmth()<br />&nbsp; &nbsp; For Q As Integer = 0 To 64<br />&nbsp; &nbsp; &nbsp; Frm.DoIt(Q)<br />&nbsp; &nbsp; &nbsp; Thread.Sleep(100)<br />&nbsp; &nbsp; Next Q<br /><br />&nbsp; &nbsp; Frm.DoIt(Now())<br />&nbsp; End Sub<br />End Class</code></dd></dl><br /><dl class="codebox"><dt>Код: <a href="#" onclick="selectCode(this); return false;">Выделить всё</a></dt><dd><code>c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\vbc.exe /target:winexe /optimize+ /debug- /out:Invoker.exe /imports:System.Windows.Forms /main:Form1 *.vb<br />start Invoker.exe</code></dd></dl><br />PS: <span class="inlinecodebox syntaxkeyword">Demo<span style="color: #BF0000">K</span>lass</span> - издеваешься что ли? Я 15 минут думал, почему код не компилируется!</div>
или изменить css (не удалить, а изменить параметр overflow)? Если скролла действительно нет, обнови или поменяй браузер.

Ты разобрался наконец с Invoke?

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 16.09.2012 (Вс) 2:26

Да, разобрался.

Dimitriy
Начинающий
Начинающий
 
Сообщения: 14
Зарегистрирован: 25.10.2011 (Вт) 6:44

Re: Выполнение процедуры класса в отдельном потоке

Сообщение Dimitriy » 16.09.2012 (Вс) 3:38

Вообще я начал разбираться с многопоточностью вот почему: регулярно встает задача инвентаризации установленного программного обеспечения на рабочих станциях, в связи с этим возникла идея сделать небольшую програмку, которая опрашивает реестр рабочих станций по сети на предмет информации об установленном ПО, затем заносит информацию в файл БД MS SQL CE. Програмка была реализована в однопоточном режиме, в связи с чем во время опроса форма программы "замерзала".

anvg
Обычный пользователь
Обычный пользователь
 
Сообщения: 66
Зарегистрирован: 20.05.2007 (Вс) 18:04

Re: Выполнение процедуры класса в отдельном потоке

Сообщение anvg » 17.09.2012 (Пн) 7:26

Господа, помогите разобраться с реализацией Invoke для пользовательского класса, так как, насколько я понял, текущее обсуждение было посвящено использование метода Invoke для формы и элементов управления.
Пусть есть класс, который запускает обработку в потоке
Код: Выделить всё
Public Delegate Sub SimpleEvent()

Public Class AsForm
    Private FDoNextItem As SimpleEvent
    Private FThreadId As Integer
    Private Sub DoNextItem()
        Console.WriteLine("{0} <> {1}", FThreadId, Threading.Thread.CurrentThread.ManagedThreadId)
    End Sub

    Private Sub OnNextItem()
        FDoNextItem.Invoke()
    End Sub

    Public Sub New()
        Dim pRun As New Runner
        Dim pThread As New Threading.Thread(AddressOf pRun.Run)
        FDoNextItem = AddressOf Me.DoNextItem
        FThreadId = Threading.Thread.CurrentThread.ManagedThreadId
        AddHandler pRun.NextItem, AddressOf Me.OnNextItem
        Console.WriteLine("Current id {0}", Threading.Thread.CurrentThread.ManagedThreadId)
        pThread.Start()
    End Sub
End Class

Класс, который собственно выполняет метод в потоке и создаёт некоторое событие при выполнении
Код: Выделить всё
Public Class Runner
    Public Event NextItem As SimpleEvent
    Public Sub Run()
        Console.WriteLine("Current id {0}", Threading.Thread.CurrentThread.ManagedThreadId)
        RaiseEvent NextItem()
    End Sub
End Class

Как сделать, чтобы метод DoNextItem() выполнялся в том же потоке, что и объект класса AsForm?
В направлении каких классов .Net следует двигаться?


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10

    TopList