2013-12-09 23 views
3

我已經設法在線程中獲取我想要的數據,但是我無法將數據傳回主線程(GUI)。VB網絡 - 將數據從線程傳遞到主GUI

我從網絡流中的線程抓取數據,則需要將它傳遞給我的主線程,以便傳遞給其他類等

我已經看到了它提到使用的BackgroundWorker這個,但由於我期望它能夠定期收集數據並永不停止,因此我認爲爲此的單獨線程將是最好的,但我對多線程很陌生。

如果線程是正確的路要走,我怎麼能從它傳回數據回我的主線程,以便用於其他的東西?我看過很多代表和事件,但是看不到我會如何傳遞數據?

感謝

+0

考慮使用'Async'方法來替代在UI線程上等待無限循環的網絡。 – SLaks

+0

謝謝 - 我可以通過一個類的自定義事件傳遞數據嗎? – Jonno

+0

在相同的線程上沒有觸發器。 – user1937198

回答

6

請研究這個例子,讓我知道這是否符合您的要求:需要

enter image description here

控制: lstItems(列表框),btnStart(按鈕),btnStop(按鈕),Timer1(定時器)。

Form 1代碼:

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:是的,你明白了。您可以進一步改進以轉儲舊消息(如果未被main使用),以防止內存溢出。請不要忘記接受/ upvote。 – Neolisk

相關問題