【问题标题】:Can't get thread to start in vb.net无法在 vb.net 中启动线程
【发布时间】:2025-12-02 23:30:01
【问题描述】:

我正在尝试在一个表单中为一个需要大约 5 秒才能运行的函数启动一个线程,这样我就可以防止 UI 被锁定。我有下面的代码,但是当它点击“thread1.start”时它失败了。当我通过调试器观看它时,它只是进入“End Sub”并且它没有进入我期望它去的 getSecurityStuff() 方法。有什么想法吗?

谢谢!

Imports System.Threading

Public Class frmAddAssets

    Private theDict As Dictionary(Of String, String) = Nothing


    Private Sub frmAddAssets_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        Control.CheckForIllegalCrossThreadCalls = False

    End Sub

    Private Sub cmbTickerEntry_Leave(sender As System.Object, e As System.EventArgs) Handles cmbTickerEntry.Leave

        Dim thread1 As New Thread(New ThreadStart(AddressOf getSecurityStuff))

        thread1.Start()

    End Sub

    Public Sub getSecurityStuff()

        Dim getData As New clsSecurityView(cmbTickerEntry.Text())

        Try
            theDict = getData.getStockData()
        Catch ex As Exception
            Throw
        End Try

        filldata()

    End Sub

    Private Sub filldata()

        Dim list As New List(Of String)(theDict.Keys)

        txtTicker.Text = cmbTickerEntry.Text.ToString()

        For Each kvp As KeyValuePair(Of String, String) In theDict

            Select Case True
                Case kvp.Key = "Name"
                    txtSecurityName.Text = kvp.Value.ToString()
                Case kvp.Key = "Price"
                    txtPrice.Text = kvp.Value.ToString()
                Case kvp.Key = "Market Capitalization"
                    txtMarketCap.Text = kvp.Value.ToString()
                Case kvp.Key = "Dividend Yield"
                    txtDivYield.Text = kvp.Value.ToString()
                Case kvp.Key = "PE Ratio"
                    txtPERatio.Text = kvp.Value.ToString()
                Case kvp.Key = "EPS"
                    txtEPS.Text = kvp.Value.ToString()
            End Select

        Next

    End Sub
End Class

【问题讨论】:

  • 代码提示:不要将任何东西初始化为Nothing,这是没有意义的。
  • 您的调试器转到“End Sub”,因为那是下一行。在“getSecurityStuff”的开头放一个断点来调试新线程。
  • 感谢您的重写。我喜欢它与我相比的紧凑程度。
  • @LanceCollins:New Thread 接受的委托是 ParameterizedThreadStart,它可以采用单个 Object 参数。这将部分消除对 CheckForIllegalCrossThreadCalls = False 的需求 - 只需确保您投射它即可。

标签: vb.net winforms multithreading


【解决方案1】:

...当我通过调试器观看它时,它只是进入“结束 子”...

请注意thread1.Start() 不会阻塞当前线程。

CheckForIllegalCrossThreadCalls 设置为False 不会做任何事情,但会忽略在您访问UI 线程拥有的控件的属性时引发的异常——这也是您的问题:

  • 您创建了一个新线程
  • 新线程调用getSecurityStuff
  • 您尝试以cmbTickerEntry.Text 作为参数声明一个新的clsSecurityView
  • 例外 - 您尝试访问 UI 线程拥有的控件,同时位于另一个线程上!
  • 没有出现异常,因为您已将CheckForIllegalCrossThreadCalls 设置为False

fillData... 相同的处理方式试图访问 UI 线程之外的控件。

解决方案:使用Invoke/BeginInvoke 来执行应该读取/修改UI线程拥有的控件属性的代码。

【讨论】:

  • 好建议,但我认为异常只发生在调试中,以确保不会犯这种错误。将CheckForIllegalCrossThreadCalls 设置为False 应该可以防止出现异常并继续使用代码...我认为问题可能出在其他地方。
  • minitech,将 CheckForIllegalCrossThreadCalls 设置为 False 不会防止异常,它会忽略它们,因此会失败。跨度>
  • msdn.microsoft.com/en-us/library/… "正在调试应用程序时。"
  • minitech,谁说他不是在调试模式下测试?我不知道你为什么觉得 CheckForIllegalCrossThreadCalls 的值只在调试模式下才有意义,而 Lance Collins 没有说明他如何运行应用程序。
  • 试试看:只需打开一个新的 Windows 窗体应用程序并粘贴 this 即可。然后取消注释该行。它有效——InvalidOperationException 是为了防止同步错误。我的意思是这可能不是问题的根源。
【解决方案2】:

试试这个

Dim action as New Action(AddressOf getSecurityStuff)
action.BeginInvoke(Nothing, Nothing)

【讨论】:

  • 那会有什么帮助?除了使用线程池中的线程之外,其他都是一样的。
  • @minitech OP 发布了 在点击“thread1.start”时失败。因此我的建议是尝试不同的语法可能会有所帮助。
最近更新 更多