子线程操作窗体上的控件,此线程或委托如何终止?

皮特胖胖 2014-05-17 07:50:51
使用多线程控制 Form1 上的 Label 显示,相关代码如下:


'声明委托
Delegate Sub DelegateThreadTask()
'局部变量:
Private thread_DisplayControl As Thread, delegate_DisplayControl As DelegateThreadTask

'开始按钮
Private Sub btnBegin_Click(sender As Object, e As EventArgs) Handles btnBegin.Click
thread_DisplayControl = New Thread(AddressOf ThreadDisplayControl) '实例一下线程
thread_DisplayControl.Start() '线程开始
End Sub
'终止按钮
Private Sub btnAbort_Click(sender As Object, e As EventArgs) Handles btnAbort.Click
thread_DisplayControl.Abort() '线程终止
End Sub

'线程
Private Sub ThreadDisplayControl()
Debug.WriteLine("线程里调用委托")
delegate_DisplayControl = New DelegateThreadTask(AddressOf SubDisplayControl)
Invoke(delegate_DisplayControl)
Debug.WriteLine("委托结束啦!")
End Sub
'委托调用
Private Sub SubDisplayControl()
Do
'每隔1秒钟,循环更新Form1上的Label信息
lblControl.Text = Now
Delay(1000) '延时函数
Loop
End Sub



然后按开始按钮,执行后线程根本停不下来(或者说线程可以停下来,但线程调用的委托停不下来)。。
本人菜鸟,请教高手。。
...全文
190 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
bwangel 2014-05-18
  • 打赏
  • 举报
回复
线程的方法跑完了它就终止了。 在.net框架下,不需要过多考虑资源释放的问题。CLR已经帮你都做了。
皮特胖胖 2014-05-18
  • 打赏
  • 举报
回复
引用 5 楼 iyomumx 的回复:
给你几个建议。 1.不要再Invoke里阻塞线程,尤其是调用Thread.Sleep或者等待线程同步对象(比如锁) 2.要终止一个线程,最好由线程自行退出。 对于你的情况可以像这样处理: 在类级别定义一个标志字段,指示线程是否需要终止
Dim NeedStop As Boolean = False
把循环和等待放到线程里进行,每次循环体检查线程是否需要终止,如果是,停止循环,做清理工作后退出
        Do Until NeedStop
            Invoke(Sub()
                          lblText.Text = ""
                      End Sub)
            Delay(1000)
        Loop
        '其他清理工作
谢谢回复~~目前看来暂时只有这个办法了。。 弱弱的问一下,清理工作,是指线程里创建的所有对象都需要手动销毁吗?

    Public Sub TestThread()
        Dim testStr As String, testInt As Integer, testObj As Object
        Dim NeedStop As Boolean = False
        Do Until NeedStop
            '上面定义的 testStr\testInt\testObj 进行赋值等操作
        Loop
        '清理工作是这样做的吗?
        testStr = Nothing : testInt = Nothing : testObj = Nothing
    End Sub
我突然灵光一闪,想到一个方案,不知道可行否。。 1、解释为什么我想从外部来结束这个线程或委托 由于线程执行的委托里有调用好多的Sub、Funtion过程,而且每个调用的过程都可能出错,如果在每个Sub、Funtion过程调用之后都进行判断是否退出,感觉还是有点麻烦的。。所以我才会想用一个外部过程来终止这个线程/委托。。 2、解释为什么需要使用委托 不使用委托的情况下(即委托的所有代码全部放到线程的Sub里执行),外部直接执行线程的Abort命令,一般是可以终止此线程的,不过很容易出问题,所以我不得不用委托来执行。。除了委托,直接由界面调用也是可行的(比如Button1的Click事件里直接调用委托的Sub过程) 3、我想到的方案 我理解的委托含义如4楼所述(不知道对不对),我觉得这也是为什么只用线程不用委托就会出问题,而直接界面调用没问题的原因。。 所以我想创建一个新的窗体Form2,在Form2的Load事件中直接调用我想要进行的操作(即上面委托里的操作),然后通过一个共享变量值来判断是否需要结束,结束操作由Form1来循环判断并执行。。。 终止命令我搜到了一些API函数,如DestroyWindow、TerminateProcess、NtTerminateProcess 目前测试下来还是小有进展的。。 大侠评论一下我这个想法吧~~
iyomumx 2014-05-18
  • 打赏
  • 举报
回复
给你几个建议。 1.不要再Invoke里阻塞线程,尤其是调用Thread.Sleep或者等待线程同步对象(比如锁) 2.要终止一个线程,最好由线程自行退出。 对于你的情况可以像这样处理: 在类级别定义一个标志字段,指示线程是否需要终止
Dim NeedStop As Boolean = False
把循环和等待放到线程里进行,每次循环体检查线程是否需要终止,如果是,停止循环,做清理工作后退出
        Do Until NeedStop
            Invoke(Sub()
                          lblText.Text = ""
                      End Sub)
            Delay(1000)
        Loop
        '其他清理工作
皮特胖胖 2014-05-17
  • 打赏
  • 举报
回复
引用 3 楼 sp1234 的回复:
你自己的线程中就不应该有什么循环、阻塞。 如果你想用低级的Timer,那么就用现成的。自己设计的应该是更高级的分层系统。 应该重新审查你自己的设计逻辑。
谢谢大哥,不过我目前刚学编程,对这些逻辑方面还没有达到那么高的境界。。 http://bbs.csdn.net/topics/320095153 这个帖子,大哥之前回复过,我的问题大概与此类似的吧。。 invoke 解释是:在拥有此控件的基础窗口句柄的线程上执行指定的委托 我理解的含义是:线程里的委托执行后可能嵌入到Form1所在句柄的线程上了,我不清楚这个情况的委托能不能终止,如果终止了,委托里创建的一系列对象会不会自动销毁,会不会影响Form1的正常运行。。 BeginInvoke和Invoke的区别我已经知道了。。EndInvoke我还在试着理解,不知道适不适用。。 头大ing...
  • 打赏
  • 举报
回复
你自己的线程中就不应该有什么循环、阻塞。 如果你想用低级的Timer,那么就用现成的。自己设计的应该是更高级的分层系统。 应该重新审查你自己的设计逻辑。
皮特胖胖 2014-05-17
  • 打赏
  • 举报
回复
引用 1 楼 sp1234 的回复:
有了 System.Threading.Timer,用你自己写什么“线程”?
其实我想做的程序比这个复杂很多,需要用到线程与窗体通信,另外还有一个共享变量来判断线程执行过程中是否出问题,出了问题就要结束它。。
  • 打赏
  • 举报
回复
有了 System.Threading.Timer,用你自己写什么“线程”?
在码农的生活中,很多级码农都有这样的经历,会被一个小小的技术问题拦住,然后进度跟不上了,被老板XXXX一大通了。心情不爽了。 好吧,这个曾经是我遇到拦路虎之一。但事实上不是什么大技术。技术就是一层纸,破了就破了。 这是一个关于如何跨窗体操作控件或过程的一个例。比如,你想用窗体A的按键来执行窗体B的文本框变色。 Imports System Imports System.Threading Imports System.Text Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load CheckForIllegalCrossThreadCalls = False '不写这行,会出错,不允许线程的数据写到TextBox1.Text 中去。 Form2.Show() End Sub Private Sub form1_FormClosing(sender As Object, e As EventArgs) Handles Me.FormClosing ' If runThread.IsAlive = True Then runThread.Abort() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click '用的是委托方式 Me.Invoke(New MethodInvoker(AddressOf THREAD2)) End Sub Private Sub THREAD2() Static j As Integer j = j + 1 TextBox1.Text = " 这是 [线程] 操作" & vbCrLf & _ " Button2被点了: " & j & " 次" & vbCrLf & "要求是from2.textbox.text= textbox1.text 。[问题]但为什么不能成功显示呢?" End Sub Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged Form2.TextBox1.Text = TextBox1.Text End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Static j As Integer j = j + 1 TextBox1.Text = " 这是 [非线程] 操作" & vbCrLf & _ "Button3 点击了: " & j & " 次" & vbCrLf & _ "要求是from2.textbox.text= textbox1.text, 可以成功显示,这个是对的。" End Sub End Class

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧