Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I've read this post: http://www.xtremedotnettalk.com/showthread.php?t=76924

 

and have successfully created a thread without using the backgroudnworkerprocess doing this

   Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
       Dim DBSyncThread As Threading.Thread
       Dim DBSyncThreadStart As New Threading.ThreadStart(AddressOf DBSync)

       DBSyncThread = New Threading.Thread(DBSyncThreadStart)
       DBSyncThread.IsBackground = True
       DBSyncThread.Name = "DBSync"
       DBSyncThread.Start()

   End Sub
   Private Sub DBSync()
       MsgBox("ehasdf boogieman")
       Functions.LogError("boogieman")
   End Sub

 

the functions.logerror call is a class that takes the passed string and sticks it into a listview on my form then writes that string to a logfile as well.

 

in the above code the messagebox pops up but the string 'boogieman' never makes it to the list. other areas of my project that arn't threaded use that logerror function very heavily (verbose). i just need to get this thread to be able to write to it too.

 

I saw on the above url that I needed to use

 

Dim threadfunction As New MethodInvoker(AddressOf nonthreadfunction)

 

and in the thread i use Me.BeginInvoke(threadfunction)

 

but those are sub routines and trying to tie in my function that passes the string just confuses the hell out of me.

 

please advise.

Posted

Well.. I Wrote up a similar app to start fresh that looks like this

Public Class Form1

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

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim t As Threading.Thread = New Threading.Thread(AddressOf filllist)
       t.IsBackground = True
       t.Start()

   End Sub
   Private Sub filllist()
       MsgBox("TEst")

       If Me.InvokeRequired = True Then

           Dim test = New Class1

           test.tester("test")

           Dim mi As New MethodInvoker(AddressOf filllist)
           BeginInvoke(mi)

       Else
           Class1.tester("test")
           Dim i As Integer
           For i = 1 To 5000
               ListBox1.Items.Add(i)
           Next
       End If

   End Sub

End Class


Public Class Class1
   Public Shared Function tester(ByVal e As String)
       Form1.ListBox1.Items.Add(e)
       tester = 0
   End Function
End Class

 

That actually works. So you get my idea. Soemtimes I need to add to a listbox under the normal thread, sometimes i need to add to it under a seperate thread.

 

I have a feeling I'm not going about the best way, but it does work on THIS sample..

 

My big program its still not working. It wont fail with an error, but the text never makes it to the control.

Posted

Nevermind, I spoke too soon, I wasn't paying attention to my own code, if it had worked I would see TWO 'test' in the listbox, im still only seeing the non threaded one.

 

You get what I need now though. IF you guys can make the above code work. I'd be so greatful.

  • Administrators
Posted

The first call to test.tester isn't being done on the UI Thread, therefore you are encountering the problem the BeginInvoke call is designed to fix.

 

Also you could have done Class1.tester for both calls to the function rather than creating an instance of Class1.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

i know. thats what i need to happen. ya i got it figured out how to populate the boxes, but i hav to be able to call that function and pass data to it from one thread to the ui thread.

 

see. the listbox is a log, very verbose of every action in the program, whats goign on, from what call to where, who clicked what etc. i have to be able to fill it from any thread. i wrote a shared function so that any form could pass data to it. the code above is just a sample. but like you said it wont work. populating the listboxes was easy, you can methodinvoke a sub routine. how do i do it fo ra function?

  • Administrators
Posted

The Form's .Invoke method has an overloaded version that allows you to pass in an array of Parameters to the function itself. I've just tweaked your code so the check fo InvokeRequired is done inside the Class1.tester method rather than the calling method.

The MethodInvoker delegate doesn't allow for parameters / return types so I've also defined a custom delegate for the tester method.

Public Class Form1

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

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim t As Threading.Thread = New Threading.Thread(AddressOf filllist)
       t.IsBackground = True
       t.Start()

   End Sub
   Private Sub filllist()
      
       Dim i As Integer
       For i = 1 To 5000
           Class1.tester(i.ToString())
       Next
      
   End Sub

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       Class1.OutputForm = Me
   End Sub
End Class


Public Class Class1
   Public Delegate Function TesterDelegate(ByVal e As String) As Integer

   Public Shared OutputForm As Form1

   Public Shared Function tester(ByVal e As String) As Integer
       If OutputForm.InvokeRequired Then
           Dim o() As Object = {e}
           Dim mi As New TesterDelegate(AddressOf tester)
           OutputForm.Invoke(mi, o)
       Else
           OutputForm.ListBox1.Items.Add(e)
       End If

       tester = 0
   End Function
End Class

 

I've changed a couple of other things - the filllist method now calls the .tester method rather than the listbox directly and the Class1 now stores a reference to the output form rather than going through the default instance of Form1.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted
I see only one problem, had i mentioned it earlier maybe it would have saved some time? but this function is called form multiple forms (thats why i put it in a class. except. im learning that more and more functions should probably go in classes, either way), so using outputform = form1, it wont work when form2 calls the same function in the same manner.
Posted
Will each form log to the same place or to a seperate place? If they are all loging to the same form then as long as the outputform is pointing to the correct form for the logging to be displayed on it shouldn't be a problem.

 

I went ahead and tested my application, and it worked fine. However its not correct. when form2 calls the same function outputform is stil = to form1. if i set class1.outputform = me on form2_load() then that would be correct, but what happens when form1 calls that function again. i could see this being a problem,

 

what happens if i always use the methodinvoke, regardless if its needed or not.

 

edit... i see that outputform has to = the form im writing the data to, which is the listview on form1. so this should always work. nevermind my previous rant, im still learning. :)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...