c# - 为什么我的线程没有立即启动?

标签 c# .net vb.net winforms multithreading

请看下面的程序。 我用函数 abc 启动了一个新线程 x,然后我做了一些更长的任务。 为什么 x 只在 end sub 之后开始?它不应该在 sleep 前立即开始吗?

 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim x As New Threading.Thread(AddressOf abc)
        x.SetApartmentState(Threading.ApartmentState.MTA)
        x.Start()

        System.Threading.Thread.Sleep(5000)
    End Sub





Sub abc()
    For i As Integer = 0 To 10 Step 1
        Me.lblStatus.Text = "Testing DB connection ( timeout in: " + i.ToString() + "s )"
        'Me.StatusStrip1.Invoke(
        MsgBox(i.ToString)
        System.Threading.Thread.Sleep(1000)
    Next
End Sub



编辑:
解决方案是这样的:

(A) 将连接尝试和超时倒计时都放在单独的线程中。
(B) 像这样更新 UI:

    If Me.InvokeRequired Then
        Me.Invoke(pUpdateStatusMessage, "Successfully connected.")
    Else
        UpdateStatusMessage("Successfully connected.")
    End If

有了这个全局声明,所以不需要传递参数:

Delegate Sub t_pUpdateStatusText(ByVal strMessage As String)
Public pUpdateStatusMessage As t_pUpdateStatusText = New t_pUpdateStatusText(AddressOf UpdateStatusMessage)

Public Sub UpdateStatusMessage(ByVal strMessage As String)
    Me.lblStatus.Text = strMessage
    Me.StatusStrip1.Update()
End Sub

最佳答案

abc 函数确实会在 Button1_Click 方法结束之前开始。造成困惑的是两件事

首先是您使用以下行直接从后台线程更新 UI

Me.lblStatus.Text = "Testing DB connection ( timeout in: " + i.ToString() + "s )" 

此代码不正确,以后可能会导致问题。您必须使用 Invoke 调用才能真正更改 UI。正如您在第二行所做的那样,这将我们带到下一个问题。

Invoke 调用是同步的。它通过本质上将消息推送到 Windows 消息队列并在返回之前等待它被处理来运行。您在主线程中添加的 Thread.Sleep 调用会阻止消息队列实际运行。这有效地停止了后台线程,直到 Sleep 调用完成,给人一种后台线程未运行的感觉。

关于c# - 为什么我的线程没有立即启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3856942/

相关文章:

c# - 如何在应用程序打开时更改应用程序设置(设置)?

.net - 如何将对象列表转换为对象在 VB.net 中实现的接口(interface)列表?

c# - Silverlight XML 保存不会覆盖整个文件

c# - 有没有一种简单的方法可以使 Visual Studio 2015 使用特定的 ToolsVersion?

c# - 使用 LINQ 访问文件夹

c# - 如何在实际将其发送到服务器之前显示正在上传的图像的预览

c# - 具有网络搜索功能的 Windows 应用程序

c# - 通过代码进行 nhibernate 映射,使用值对象列表映射实体

c# - Wpf控件显示html代码

c# - Escape for folder Exists and Create 目的