【问题标题】:VB Net Update GUI from Thread in a different vb file来自不同 vb 文件中的线程的 VB 网络更新 GUI
【发布时间】:2013-07-16 17:38:39
【问题描述】:

首先,我已经阅读了很多关于此的内容,但无论如何我都没有得到该死的答案。我知道我不应该从线程更新 UI,但在这种情况下,我认为这是唯一的方法。

我的应用程序发送大量电子邮件,比如说 500 封,为了避免应用程序过载,我使用线程来处理存储在 DDBB 中的信息。一切正常,我正在使用代表,我成功地通过客户端发送它们,但我希望应用程序在 MDI 表单标签中显示一条消息,内容类似于“电子邮件发送到:blabla@gmail.com 在 10:00: 00" 只是为了向用户显示进程正在后台运行...

我的代码很简单:


- 来自 MDI:

BulkThread = 新线程(New ThreadStart(AddressOf ProcessBulkList))

BulkThread.Start()


- 来自包含 ProcessBulkList 的模块:

Public Delegate Sub MySubPara(ByVal p As String)

公共子ProcessBulkList()

   Dim DelegateMDI As MySubPara = New MySubPara(AddressOf MostrarEnMDI)

   DelegateMDI.Invoke("example@gmail.com")

结束子

Public Sub MostrarEnMDI(para As String)

    MDI.LabelSMS.Text = "Message sent to: " & para & " at " & GetTime()
    MDI.Refresh()

结束子

当然,在 ProcessBulkList 函数中,有更多的委托和东西,一切都很完美,但是这个调用,在 MDI 表单上没有显示任何内容......可能我使用的 MDI 是原始 MDI 的副本,但为什么呢? ???因为使用线程调用应该使用调用主线程中元素队列的SendMessage函数,不是吗??

【问题讨论】:

    标签: multithreading


    【解决方案1】:

    好的,我刚刚找到了一个解决方案,将标签作为线程内函数的参数传递,如下所示:

    BulkThread = 新线程(Sub() ProcessBulkList(ToolStripStatusLabel1)) BulkThread.Start()

    【讨论】:

      【解决方案2】:

      在您的线程中(在真正的线程中必须通过原始表单可以显示您是否需要该示例)像这样调用委托/调用

      showLoadingPicInvoke(0, oldform) ' 0 只是在 del / invoke 方法中使用的一个变量,你不必让它们可以删除,oldform(传递给线程的原始表单是必须的。)

      Delegate Sub changeText(oldform As Form1)
      Sub changeTextInvoke(ByVal oldform As Form1)
          If oldform.InvokeRequired Then
              Dim d As New changeText(AddressOf changeTextInvoke)
              oldform.ControlName.Invoke(d, New Object() {oldform})
          Else
      

      下面是您在 Form1 ( Main Form ).vb 上更改以执行您想要的操作的地方

                  'changeText
                  'oldform.ControlName.value = value
                  'oldform.ControlName.Refresh()
      
      
          End If
      End Sub
      

      【讨论】:

      • 我已经看到结果了,但我不想一直打扰用户,我想要一些类似 Outlook 的状态栏,在那里你可以看到“Sending message 1 out of XXX”。 ..不会使系统的其余部分超载..
      • @AsuncionCarreigos codeproject.com/Articles/13547/…,在这里获取一个 - 下载应该可以解决问题的控件:P
      • 这段代码看起来不错,但我不想让自己太复杂。我只想从线程中更改 ToolstripStatusLabel 文本属性..
      • 编辑了答案以包含一个 del/invoke 示例以更改主线程上的某些内容。
      【解决方案3】:
      Delegate 上的

      Invoke 动态调用 same 线程上的委托。不涉及跨线程消息传递。要更新 GUI,需要从创建您正在修改的控件的线程(即主线程)完成更新。您需要在Control 上使用InvokeBeginInvoke 方法在正确的线程上运行您的代码。这些方法是ISynchronizeInvoke 的实现,并将调用编组到正确的线程。

      【讨论】:

      • 在我运行线程发送电子邮件之前,控件(在这种情况下为标签)已经在 MDI 表单中创建,所以我应该怎么做???有什么想法吗??
      • 再次阅读我的帖子。只需调用MDI.LabelSMS.Invoke 调用设置标签的方法,而不是直接设置标签。
      • 对不起,我没说 Label 在底部的 StatusStrip 栏上,所以我无法访问调用方法(我不知道为什么 BTW..)
      • 好的,所以我无法访问调用方法,因为它不是控件...我一直在阅读它,但我真的不明白如何完成它...有人说调用状态条相反,但是......不知道如何继续......如果我已经在一个线程中,我应该如何调用状态条???
      猜你喜欢
      • 2017-09-05
      • 1970-01-01
      • 2012-01-17
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多