当前位置: 代码迷 >> VB Dotnet >> 新手请问跨线程事件响应和显示的有关问题
  详细解决方案

新手请问跨线程事件响应和显示的有关问题

热度:96   发布时间:2016-04-25 02:08:07.0
新手请教跨线程事件响应和显示的问题
新手,多线程的部分有很多不明白,想请教一下大家,望不吝赐教
下面贴上代码,代码有两组,实际上想做的都是一件事

程序有三个部分,类Class1,窗体Form1,Form2
在Form1内实例化Class1为C1,在Form2内显示一些C1通过事件传出的信息

代码1


Imports System.Threading

Public Class Class1

    Public Event EvenNumber(ByVal n As Integer)
    Private Num As Integer
    Private StopThread As Boolean = False

    Public Sub ThdStart()
        Dim Thd As New Thread(AddressOf ThdAdd)
        StopThread = False
        Thd.Start()
    End Sub

    Public Sub ThdStop()
        StopThread = True
    End Sub

    Private Sub ThdAdd()
        Do While StopThread = False
            Thread.Sleep(1000)
            Num = Num + 1
            If Num Mod 2 = 0 Then
                RaiseEvent EvenNumber(Num)
            End If
        Loop
    End Sub

End Class


Public Class Form1

    Public WithEvents C1 As New Class1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        C1.ThdStart()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        C1.ThdStop()
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Form2.Show()
    End Sub

    Private Sub C1_EvenNumber(ByVal n As Integer) Handles C1.EvenNumber
        Me.Invoke(New Form2.DlgShowText(AddressOf Form2.ShowText), n.ToString)  'A
    End Sub

End Class


Public Class Form2

    Public Delegate Sub DlgShowText(ByVal s As String)

    Public Sub ShowText(ByVal s As String)
        TextBox1.Text = s  'B
    End Sub

End Class


A处能响应事件,并且能执行到B处,而且不报错,但是textbox1里面并不显示任何内容,请教各位高手这是为何


代码2


Imports System.Threading

Public Class Class1

    Public Event EvenNumber(ByVal n As Integer)
    Private Num As Integer
    Private StopThread As Boolean = False

    Public Sub ThdStart()
        Dim Thd As New Thread(AddressOf ThdAdd)
        StopThread = False
        Thd.Start()
    End Sub

    Public Sub ThdStop()
        StopThread = True
    End Sub

    Private Sub ThdAdd()
        Do While StopThread = False
            Thread.Sleep(1000)
            Num = Num + 1
            If Num Mod 2 = 0 Then
                RaiseEvent EvenNumber(Num)
            End If
        Loop
    End Sub

End Class


Public Class Form1

    Public WithEvents C1 As New Class1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        C1.ThdStart()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        C1.ThdStop()
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Form2.Show()
    End Sub

End Class


Public Class Form2

    Public Delegate Sub DlgShowText(ByVal s As String)

    Public Sub ShowText(ByVal s As String)
        TextBox1.Text = s
    End Sub

    Private Sub C1OnEvenNumber(ByVal n As Integer)
        Me.Invoke(New DlgShowText(AddressOf ShowText), n.ToString)  'C
    End Sub

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler Form1.C1.EvenNumber, AddressOf C1OnEvenNumber
    End Sub
End Class


打开form2可以在textbox1中正确显示,在form2从未打开时和form2已经打开时不会出错,但是只要打开过form2,然后关掉,就会在C处报错"在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。",请教高手这又是为何

冒昧邀请了五位系统推荐高手,如有打搅请见谅
------解决思路----------------------
原因很简单,窗体被关闭时被释放掉了,这个时候在invoke是没有对象的,所以要做些判断,改了下代码,暂时没错还是有不少地方要完善。

Public Class Form2
    Public Delegate Sub DlgShowText(ByVal s As String)

    Public Class Form2
    Public Delegate Sub DlgShowText(ByVal s As String)

    Public Sub ShowText(ByVal s As String)
        TextBox1.Text = s
    End Sub

    Private Sub C1OnEvenNumber(ByVal n As Integer)
        If Me.Disposing Or Me.IsDisposed Or Me.Visible = False Then
            Exit Sub
        End If

        Me.Invoke(New DlgShowText(AddressOf ShowText), n.ToString)  'C
    End Sub

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler Form1.C1.EvenNumber, AddressOf C1OnEvenNumber
    End Sub

    Private Sub Form2_FormClosed(sender As System.Object, e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed

    End Sub

    Private Sub Form2_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        e.Cancel = True
        Me.Hide()
    End Sub
End Class
  相关解决方案