VB Net-如何将数据从线程传递到主GUI?

3

我已经在一个线程中成功获取到了我想要的数据,但是我不知道如何将数据传回主线程(GUI),希望您能够帮我解决这个问题。

我正在从网络流中抓取数据,并需要将其传递给主线程,以便传递给其他类等。

我看到有人提到使用 backgroundworker 来完成此操作,但由于我期望它可以定期收集数据并且永远不会停止,因此我认为使用另一个线程可能更好,但我对多线程非常陌生。

如果使用线程是正确的方法,那么我如何将数据从线程传回主线程以便用于其他操作?我经常看到代理和事件被提到,但是不知道如何使用它们来传递数据?

谢谢


考虑在UI线程上使用一个无限循环的异步方法来等待网络的响应。 - SLaks
谢谢 - 我可以从一个类中使用自定义事件传递数据吗? - Jonno
没有事件在同一线程上触发。 - user1937198
除非你需要访问UI,否则为什么需要将其传回主线程?在线程上进行处理即可。 - user1937198
基本上它会每隔几秒钟生成字符串,我想把它们放到主 UI 上的列表框中。 - Jonno
1个回答

6
请研究这个例子,如果符合您的要求,请告诉我:
控件需求: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

字符串生成器代码:

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

这个并没有经过广泛测试,但它应该能够帮助你有一个良好的开端。

刚试用了一下...看起来不错。如果我没理解错的话,它会将字符串按顺序添加到队列中,以便主线程在准备好时逐个获取它们?非常感谢您的帮助,非常有用!!! - Jonno
@JohnathonMihalop:没错,你说得对。如果主程序没有消耗掉旧消息,你可以进一步改进它以将其删除,以防止内存溢出。请不要忘记接受/点赞。 - Victor Zakharov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接