Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / WinForm General / June 2007

Tip: Looking for answers? Try searching our database.

Updating Form Controls from Separate Worker Thread - Must all code be in the same source file?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
snaga.ohme@gmail.com - 21 Jun 2007 04:06 GMT
I have a small problem that's keeping my up late....very late...

It's the standard updating the controls on a windows form from a
separate worker thread problem.

I create a simple form in VB with a Start button (to start the worker
thread) and a single label control

A simple update procedure makes the changes to the label control, i.e.
changes the label text to some value.  a delegate to this procedure is
invoked on the UI thread by the worker thread when it's time to
update.

Everything works if all my code is in the form source file, i.e.
Form1.vb., in which case the update procedure is invoked as follows:

me.invoke(updateDelegate)

If I move the code for the worker  thread to a separate source file
and contain it within a module (module1.vb), i.e.,

public Module Module1

  public sub MyThread()

 .....code

  ' invoke update delegate
   Form1.invoke(updateDelegate)

 end sub

end module

And then invoke the update delegate but now referencing the UI thread
with Form1.invoke(...) versus me.invoke(...) it will not work.

I get the following error:

Invoke or BeginInvoke cannot be called on a control until the window
handle has been created.

Is there a requirement that everything be in the same source file?
Bryan Phillips - 21 Jun 2007 04:38 GMT
All code does not need to be in the same source file, but you will need
to have access to an instance of the form in question in your MyThread
sub.

--
Bryan Phillips
MCT, MCSD, MCDBA, MCSE
Blog:  http://bphillips76.spaces.live.com
Web Site:  http://www.composablesystems.net

> I have a small problem that's keeping my up late....very late...
>
[quoted text clipped - 39 lines]
>
> Is there a requirement that everything be in the same source file?
snaga.ohme@gmail.com - 21 Jun 2007 05:19 GMT
> All code does not need to be in the same source file, but you will need
> to have access to an instance of the form in question in your MyThread
[quoted text clipped - 53 lines]
>
> > Is there a requirement that everything be in the same source file?

That's what I thought...I guess for some reason I'm not grabbing the
right instance.  There is only one form...here is the code that works
and doesn't - maybe you can spot my mistake.  Code below is for a
single form with one text box and one button.  Worker Thread simply
updates the text in the text box.  Since I see a form pop up on the
screen I don't understand why I get the exception that I do....

++++++++++++++++++++ THIS WORKS +++++++++++++++++++++++++++++++++++++
+    All code in one file, Form1.vbs
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
imports System.threading

Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
       Dim t As New Thread(AddressOf MyThread)
       t.Start()
   End Sub

   Public Delegate Sub UpdateDelegate(ByVal msg As String)

   Public Sub UpdateTextBox(ByVal msg As String)
       TextBox1.Text = msg
   End Sub

   Public Sub MyThread()
       ' Call the delegate to update the label text
       Dim updateDelegate As New UpdateDelegate(AddressOf
UpdateTextBox)
       Me.Invoke(updateDelegate, "Test")

   End Sub

   Private Sub TextBox1_TextChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles TextBox1.TextChanged

   End Sub
End Class

++++++++++++++++++++++++++ THIS WILL NOT WORK++++++++++++++++++++++++++
+++++++++++++++++++++
+  code in files form1.vbs and module1.vbs
+
+  hitting the text button throws exception in line
"Form1.Invoke(updateDelegate, "Test")
+  "Invoke or BeginInvoke cannot be called on a control until the
window handle has been created."
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++
[Form1.vbs]
-------------------------
imports System.threading

Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
       Dim t As New Thread(AddressOf MyThread)
       t.Start()
   End Sub

   Private Sub TextBox1_TextChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles TextBox1.TextChanged

   End Sub
End Class

[module1.vbs]
--------------------
Module Module1

   Public Delegate Sub UpdateDelegate(ByVal msg As String)

   Public Sub UpdateTextBox(ByVal msg As String)
       Form1.TextBox1.Text = msg
   End Sub

   Public Sub MyThread()
       ' Call the delegate to update the label text
       Dim updateDelegate As New UpdateDelegate(AddressOf
UpdateTextBox)
       Form1.Invoke(updateDelegate, "Test")

   End Sub
End Module
Bryan Phillips - 24 Jun 2007 02:25 GMT
You need to pass the instance of Form1 to the two functions which will
look like this:

Form1.vb
---------------------

...

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
    Dim t As New Thread(AddressOf MyThread)
    t.Start(Me)  ' <- Pass the instance of Form1 to the MyThread
subroutine.
End Sub

...

Module1.vb
---------------------

...

Public Delegate Sub UpdateDelegate(ByVal msg As String, ByVal f As
Form1)

Public Sub UpdateTextBox(ByVal msg As String, ByVal f As Form1)
    f.TextBox1.Text = msg
End Sub

Public Sub MyThread(ByVal data As Object) ' <- This is the signature for
a ParameterizedThreadStart delegate.
    ' Convert data to a Form1 object.
    Dim f As Form1 = CType(data, Form1)

    ' Call the delegate to update the label text
    Dim updateDelegate As New UpdateDelegate(AddressOf UpdateTextBox)

    f.Invoke(updateDelegate, "Test", f) ' <- Here we are passing the Form1
instance again.

End Sub

...

I hope this helps.

--
Bryan Phillips
MCT, MCSD, MCDBA, MCSE
Blog:  http://bphillips76.spaces.live.com
Web Site:  http://www.composablesystems.net

> > All code does not need to be in the same source file, but you will need
> > to have access to an instance of the form in question in your MyThread
[quoted text clipped - 141 lines]
>     End Sub
> End Module

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.