Tree structure and threads in VB.NET


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 7 of 7

Thread: Tree structure and threads in VB.NET

  1. #1
    Join Date
    Feb 2007
    Posts
    16

    Exclamation Tree structure and threads in VB.NET

    Hi all,
    I am trying to communicate a serial device with my program. My program need to read the information coming through the device. Everything is OK so far. But I am doing this "information reading" using a thread.

    Let me show some of the codes:

    Code:
    Dim thr As Threading.Thread = New Threading.Thread(AddressOf read_data)
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            thr.Start()
    End Sub
    When I click the button, the program reads the data. But when I click once more an exception occurs: Thread is running or terminated; it cannot restart.

    As far as i see, The thread thr runs when i click the button and then it dies. When i click the button one more thread thr cannot be run again.

    Consequently, I have to make the thread thr always run. How can I do this?
    I have tried thr.abort() method. but it didn't work.

    I need your help. I think a simple Try-Catch handling operation solves my problem, but i don't know how to write those codes. I don't understand Try-Catch operation so much. I am new on VB.NET.

  2. #2
    Join Date
    Jan 2007
    Posts
    112
    Once a thread finishes it can't be restarted. You need to create a new instance of the thread.

    Try changing your code to this.

    Code:
    Dim thr As Threading.Thread
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            'Prevents multiple threads from being created
            'You may want to kill the thread instead of returning.  thr.abort would do that
            'If you don't use the next line to abort or return then multiple threads will run but thr will only reference the newest
            if thr isnot nothing andalso thr.IsAlive then return
    
            'Create new instance of the thread
            thr = New Threading.Thread(AddressOf read_data)
            thr.Start()
    End Sub
    Last edited by TwoFaced; 02-19-2007 at 02:16 PM.

  3. #3
    Join Date
    Feb 2007
    Posts
    16

    Exclamation It did not work

    Thank you for your interest. I am glad to get an answer. But this did not solve my problem. Because another exception occurs when I try the codes that you have sent.

    let me show you whole program codes and you decide what to do:

    Code:
    Imports System.IO
    Imports System.Threading.Thread
    
    Public Class olcu
        Dim thr As Threading.Thread 'This line was replaced with the line below.
        'Dim thr As Threading.Thread = New Threading.Thread(AddressOf bilgial) 'Read_data thread
        Dim gelenstr As String = "" 'A string object for coming data from port
        Dim com1 As IO.Ports.SerialPort = My.Computer.Ports.OpenSerialPort("COM2", 9600, IO.Ports.Parity.None, 8, IO.Ports.StopBits.One) 'This line is for communication port declaration
        Private Sub olcu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            txttarih.Text = Now 'Gets the current date and time of measure of weight
            'The recent measuring information is called from DB file
            txtadi.Text = ds1.Tables("kimlik").Rows(0).Item(2)
            txtyas.Text = ds1.Tables("kimlik").Rows(0).Item(3)
            txtcins.Text = ds1.Tables("kimlik").Rows(0).Item(4)
            txtboy.Text = ds1.Tables("kimlik").Rows(0).Item(5)
            da_doldur("select * from kilo where kimlikno='" & Kullanici_Giris_Form.txtkimlik.Text & "' order by tarih desc", "kilo")
            If ds1.Tables("kilo").Rows.Count > 0 Then
                txtsontarih.Text = ds1.Tables("kilo").Rows(0).Item(2)
                txtsonkilo.Text = ds1.Tables("kilo").Rows(0).Item(3) & "," & ds1.Tables("kilo").Rows(0).Item(4)
                dgtarti.DataSource = ds1.Tables("kilo").DefaultView
                dgtarti.Refresh()
            Else
                MsgBox("kullanıcıya ait tartı bilgisi bulunmamaktadır.") 'No informaiton about this user!
            End If
        End Sub
    
    
        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            Me.Close()
        End Sub
    
        Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
            yeni.ShowDialog() 'Not important you can pass this
        End Sub
        Public Sub bilgial() 'Data reading method starts here
            Dim gelen As String = com1.ReadLine() 'Reads the line coming from the port to the String gelen
            If gelen Is Nothing Then
                txtkilo.Text = "Boş" '
            Else
                gelenstr &= gelen & vbCrLf
                txtkilo.Text = gelen
            End If
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
            'Prevents multiple threads from being created
            'You may want to kill the thread instead of returning.  thr.abort would do that
            'If you don't use the next line to abort or
            'return then multiple threads will run but thr will only reference the newest
            If thr IsNot Nothing AndAlso thr.IsAlive Then Return
            thr = New Threading.Thread(AddressOf bilgial)
            'Create new instance of the thread
            thr.Start()
    
    
            baglan() 'Database connection starts here
            cmnd.CommandText = "insert into kilo(kimlikno,tarih,kilo,gram) values('" & Kullanici_Giris_Form.txtkimlik.Text & "','" & txttarih.Text & "'," & CType(txtkilo.Text, Integer) & "," & CType(txtgram.Text, Integer) & ")"
            cmnd.ExecuteNonQuery()
            baglanti_kes() 'Database connection terminated
            MsgBox("yeni kilo bilgisi eklendi") 'New weight information added to DB!
            da_doldur("select * from kilo where kimlikno='" & Kullanici_Giris_Form.txtkimlik.Text & "' order by tarih desc", "kilo")
            If ds1.Tables("kilo").Rows.Count > 0 Then
                txtsontarih.Text = ds1.Tables("kilo").Rows(0).Item(2)
                txtsonkilo.Text = ds1.Tables("kilo").Rows(0).Item(3) & "," & ds1.Tables("kilo").Rows(0).Item(4)
                dgtarti.DataSource = ds1.Tables("kilo").DefaultView
                dgtarti.Refresh()
            End If
            txtkilo.Text = "" 'Cleans the weight textbox of Kilo
            txtgram.Text = "" 'Cleans the weight textbox of gram
        End Sub
    End Class
    You can see some strange definitions because of difference of my language. But I really need your help. And also I don't have any more time. In a week I have to write this program. I am a student and this is not a commercial thing. Please I am begging you.

  4. #4
    Join Date
    Jan 2007
    Posts
    112
    No need to beg I'm always happy to help The code I gave you does work in my tests so I'm not sure it's that code that's causing a problem. What exception are you getting? Where and when does it happen? I assume it happens when button1 is clicked, but are you positive it's related to my code?

    thr = New Threading.Thread(AddressOf bilgial)

    Where is the method bilgial? I assume it's in a module somewhere because I didn't notice it anywhere in your class. If it's somewhere else then please post that method so I can see if something might be going wrong with it.

    **EDIT**
    Sorry, I missed the method bilgial the first time I read through your code. I have a feeling I know the problem. You can't update UI elements from a different thread then the one it was created on. Are you getting an exception similiar to this?

    Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on.

    If that's not the current problem then it will be If it is we can easily fix that. Just get back to me on the exception your getting and I think we can figure this out.
    Last edited by TwoFaced; 02-21-2007 at 12:19 AM.

  5. #5
    Join Date
    Feb 2007
    Posts
    16

    Exclamation

    I wrote "If thr IsNot Nothing AndAlso thr.IsAlive Then thr.Abort()" and then when I click Button it records the coming data. But I click one more time an exception occurs: "Safe handle has been closed" which is titled as ObjectDisposed Exception unhadled




    I wrote "If thr IsNot Nothing AndAlso thr.IsAlive Then Return"
    and then when I click Button it records the coming data. But I click one more time after recording. It does nothing.

  6. #6
    Join Date
    Jan 2007
    Posts
    112
    Quote Originally Posted by ozkanozlu
    I wrote "If thr IsNot Nothing AndAlso thr.IsAlive Then thr.Abort()" and then when I click Button it records the coming data. But I click one more time an exception occurs: "Safe handle has been closed" which is titled as ObjectDisposed Exception unhadled




    I wrote "If thr IsNot Nothing AndAlso thr.IsAlive Then Return"
    and then when I click Button it records the coming data. But I click one more time after recording. It does nothing.
    Nice, I think that information helped me isolate the problem. I tried testing your code and I believe if com1.readline has nothing to read it just waits and never returns. You said it read the information but are you sure? I don't think it did. In my test, code after that line never executed. When I tried running the thread again my procedure exited because the thread was still alive, which is exactly what happend when you used "If thr IsNot Nothing AndAlso thr.IsAlive Then return". However, when you tried using "If thr IsNot Nothing AndAlso thr.IsAlive Then thr.abort" you got an error. I also recieved the same error and it wasn't due to my code. I think when the thread was killed the com1 object was still trying to read the data. When the thread is suddenly aborted you get an error from com1. Try the following change.

    Code:
    Public Sub bilgial() 'Data reading method starts here
            Dim gelen As String = com1.ReadLine 'Reads the line coming from the port to the String gelen
    
           'If I am right this code should never execute.
            MsgBox("Data was read")  'Display message proving we got this far
            If gelen Is Nothing Then
                txtkilo.Text = "Boş" '
            Else
                gelenstr &= gelen & vbCrLf
                txtkilo.Text = gelen
            End If
        End Sub
    Because I don't really know what com1.Readline is supposed to do I can't really help. Is it supposed to just wait for information? If that's the case you don't need to run the thread again until it got the data. In that case just use "If thr IsNot Nothing AndAlso thr.IsAlive Then return". This should exit the procedure because the thread is alive and still waiting for information. It may not be reading from your seriai port correctly, which could also be why it never returns. One change I made was to set a timeout of 1 second form the com1 object.
    Code:
        Public Sub bilgial()  'Data reading method starts here
           'Sets a time out of 1 second
            com1.ReadTimeout = 1000
    
            Dim gelen As String = Nothing
            Try
                gelen = com1.ReadLine 'Reads the line coming from the port to the String gelen
            Catch ex As System.TimeoutException
                'Catch the timeout exception
            End Try
    
            If gelen Is Nothing Then
                txtkilo.Text = "Boş" '
            Else
                gelenstr &= gelen & vbCrLf
                txtkilo.Text = gelen
            End If
        End Sub
    With the above code I give the com1 object a maximum of a second to read the data. If it can't an exception is thrown which I catch in the try catch block. The procedure should then finish normally and the thread will die allowing you to start it again.

  7. #7
    Join Date
    Feb 2007
    Posts
    16
    OK! That is it! I did it! As you said 2Faced, I wrote the codes below. And everything is now OK.

    Code:
    if thr isnot nothing andalso thr.IsAlive then return
    
            'Create new instance of the thread
            thr = New Threading.Thread(AddressOf read_data)
            thr.Start()
    Thank you very much.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center