2013-12-09 3 views
3

Мне удалось получить данные, которые я хочу в потоке, однако у меня возникают проблемы с передачей данных обратно в основной поток (GUI).VB Net - Передача данных из Thread to Main GUI

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

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

Если поток является правильным способом, как я могу передать данные из него обратно в основную тему, чтобы использовать это для других вещей? Я видел, как делегаты и события много упоминались, но не могут понять, как я передам данные с ними?

Благодаря

+0

Рассмотрите возможность использования метода «Async», который «Ожидает» сеть в бесконечном цикле на потоке пользовательского интерфейса. – SLaks

+0

Спасибо - могу ли я передавать данные с помощью специального события из класса? – Jonno

+0

В одной и той же теме нет триггеров. – user1937198

ответ

6

Пожалуйста, изучающие этот пример, и дайте мне знать, если он соответствует вашим требованиям:

enter image description here

управления требуется: lstItems (ListBox), btnStart (кнопка), btnStop (), Timer1 (Таймер).

Form1 код:

Public Class Form1 
    Dim p_oStringProducer As StringProducer 

    Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click 
    p_oStringProducer = New StringProducer 
    p_oStringProducer.Start() 
    Timer1.Enabled = True 
    End Sub 

    Private Sub btnStop_Click(sender As Object, e As EventArgs) _ 
                  Handles btnStop.Click 
    Timer1.Enabled = False 
    p_oStringProducer.Stop() 
    End Sub 

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick 
    Dim asQueue As Concurrent.ConcurrentQueue(Of String) = 
     p_oStringProducer.MessageQueue 
    While asQueue.Count > 0 
     Dim sItem As String = Nothing 
     asQueue.TryDequeue(sItem) 
     lstItems.Items.Add(sItem) 
    End While 
    End Sub 
End Class 

код StringProducer:

Imports System.Threading.Tasks 

Public Class StringProducer 
    Private p_fKeepRunning As Boolean 
    Private p_oTask As task 
    Private p_aMessageQueue As Concurrent.ConcurrentQueue(Of String) 
    Private p_iNextMessageId As Integer 

    Public ReadOnly Property MessageQueue As _ 
          Concurrent.ConcurrentQueue(Of String) 
    Get 
     Return p_aMessageQueue 
    End Get 
    End Property 

    Sub New() 
    p_oTask = New Task(AddressOf TaskBody) 
    p_aMessageQueue = New Concurrent.ConcurrentQueue(Of String) 
    p_iNextMessageId = 0 
    End Sub 

    Public Sub Start() 
    p_fKeepRunning = True 
    p_oTask.Start() 
    End Sub 

    Public Sub [Stop]() 
    p_fKeepRunning = False 
    End Sub 

    Private Sub TaskBody() 
    While p_fKeepRunning 
     Threading.Thread.Sleep(2000) 
     p_aMessageQueue.Enqueue("Message #" & p_iNextMessageId) 
     p_iNextMessageId += 1 
    End While 
    End Sub 

    Protected Overrides Sub Finalize() 
    MyBase.Finalize() 
    Me.Stop() 
    End Sub 
End Class 

Это не тщательно протестированы, но это должно дать вам фору.

+0

Просто быстро пошел с ним ... Выглядит хорошо. Если я понимаю, он добавляет строки в очередь, чтобы основной поток воспринимал их индивидуально, когда и когда он готов? Большое спасибо за вашу помощь, очень полезно !!!! – Jonno

+0

@JohnathonMihalop: Да, вы поняли. Вы можете еще больше улучшить его, чтобы сбрасывать старые сообщения, если они не используются основной, для предотвращения переполнения памяти. Пожалуйста, не забудьте принять/увеличить. – Neolisk