为什么我的线没有立即开始?
【腾讯云】亏本大甩卖,服务器4核16G 1年370元(带宽12M,系统盘120GB SSD盘,月流量2000GB)!!!!!!
云产品 配置 价格
服务器 1核2G,带宽5M,系统盘50GB SSD盘,月流量500GB 38元/年
MySQL 1核1G 19元/年
服务器 16核32G,带宽18M,系统盘250GB SSD盘,月流量5000GB 1197元/年
点我进入腾讯云,查看更多详情

see below program. I start a new thread x with function abc, then I do some longer task. Why does x only start after end sub? Shouldn't it start right-away, before 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



Edit:
The solution is this:

(A) Put both the connection attempts and the timeout countdown into separate threads.
(B) Update the UI like this:

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

With this globally declared, so no argument passing is necessary:

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

#0

The abc function will indeed start before the Button1_Click method ends. What's causing the confusion is 2 things

The first is that you are directly updating the UI from a background thread with the following line

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

This code is incorrect and can cause issues later on. You must use the Invoke call in order to actually change the UI. As you do in the second line which brings us to the next problem.

The Invoke call is synchronous. It runs by essentially pushing a message onto the windows message queue and waiting for it to be processed before returning. The Thread.Sleep call you added in the main thread prevents the message queue from actually running. This effectively stalls the background thread until the Sleep call completes giving the appearance that the background thread is not running.

#1

You're updating your UI from a non-UI thread. This is not allowed, and can lead to odd behavior. I don't know if that's what's causing your delay behavior, but you'll need to solve that first.

#2

To add to what others are saying, you can create a delegate to define the signature of your control update requirements (in this case, I'm assuming textbox and string, but that can be defined however you need), and then create a method that follows that delegate signature which recursively invokes itself asynchronously if need be.

Something like this:

private delegate void ControlUpdateTextHandler(TextBox ctrl, string text);
public void UpdateControlText(TextBox ctrl, string text)
{
    if (ctrl.InvokeRequired)
    {
        ctrl.BeginInvoke((ControlUpdateTextHandler)UpdateControlText, ctrl, text);
    }
    else
        ctrl.Text = text;
}

Should work if it's called from the "correct" thread (because InvokeRequired will be false if this is called by the thread that owns the control) by simply updating the text, or from the "incorrect" thread (becasue InvokeRequired will be true if called from a different thread), by queuing up the invocation to be performed by the UI thread.

#3

Maybe not related to your question,but for updating the UI from a separate thread, I suggest you use the BackgroundWorker. place the abc() function in DoWork and use ProgessChanged to update the UI.

推荐文章

$.ajax忽略删除请求的数据参数

$.ajax忽略删除请求的数据参数

推荐文章

多个sql查询对性能有重大影响吗?

多个sql查询对性能有重大影响吗?

推荐文章

对读取XML数据C感到困惑#

对读取XML数据C感到困惑#

推荐文章

PHP数组合并问题

PHP数组合并问题

推荐文章

需要屏幕设计方面的帮助

需要屏幕设计方面的帮助

推荐文章

JUnit java.lang.NoSuchMethod错误:JUnit.framework.ComparisonFailure.getExpected()Ljava/lang/String

JUnit java.lang.NoSuchMethod错误:JUnit.framework.ComparisonFailure.getExpected()Ljava/lang/String

推荐文章

检索集合并枚举选定值WPF属性网格

检索集合并枚举选定值WPF属性网格

推荐文章

如何从google analytics获取我的特定链接详细信息

如何从google analytics获取我的特定链接详细信息

推荐文章

对于C#有些人必须知道什么?

对于C#有些人必须知道什么?

推荐文章

使用jQuery DataTables/Tablesorter插件时,在Firefox或Chrome中选择list change event not firing

使用jQuery DataTables/Tablesorter插件时,在Firefox或Chrome中选择list change event not firing

推荐文章

在FTP中创建目录

在FTP中创建目录

推荐文章

从批处理文件创建日志

从批处理文件创建日志

推荐文章

一年中的几个星期在鲁比循环(西纳特拉)

一年中的几个星期在鲁比循环(西纳特拉)

推荐文章

:第一次安装或使用包时运行代码

:第一次安装或使用包时运行代码

推荐文章

如何将经典的ASP与ASP.NET应用程序集成?

如何将经典的ASP与ASP.NET应用程序集成?

推荐文章

使用php/json从iphone搜索google/twitter的建议

使用php/json从iphone搜索google/twitter的建议