probleum in running the thread program

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • progvar
    New Member
    • Feb 2008
    • 40

    probleum in running the thread program

    Hi!
    i am making a program invb.net on threading but when i execute it produce the error on the progbar.Value = newval
    my program is
    Imports System.Threadin g
    Public Class Form1
    Private trd As Thread
    Private Sub Button1_Click(B yVal sender As System.Object, ByVal e As System.EventArg s) Handles Button1.Click
    MsgBox("this is main thread")
    End Sub
    Private Sub threadtask()
    Dim stp As Integer
    Dim newval As Integer
    Dim rnd As New Random()
    Do
    stp = progbar.Step * rnd.Next(-1, 2)
    newval = progbar.Value + stp
    If newval > progbar.Maximum Then
    newval = progbar.Maximum
    ElseIf newval < progbar.Minimum Then
    newval = progbar.Minimum
    End If

    progbar.Value = newval here is error and error is
    Cross-thread operation not valid: Control 'progbar' accessed from a thread other than the thread it was created on.
    Thread.Sleep(10 0)
    Loop
    End Sub

    Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As System.EventArg s) Handles MyBase.Load
    trd = New Thread(AddressO f threadtask)
    trd.IsBackgroun d = True
    trd.Start()

    End Sub
    End Class
  • balabaster
    Recognized Expert Contributor
    • Mar 2007
    • 798

    #2
    You cannot reference any property belonging to your form or objects on your form from any thread other than the main GUI thread. There are two methods you can use to achieve this:

    First method (in my opinion, this should never be used, but as I said, that's just my opinion): There is an option somewhere in Visual Studio that allows you to turn off this feature - which allows for potentially fatal scenarios. It will then stop complaining about this and allow multiple threads to update form/object properties. I forget what it's called - but usually the error message tells you.

    The Second method (and in my opinion should always be the one that is used) is to use delegates. Delegates are a bit tough to get your head around, but I will do my best to explain. Firstly I'll give a code example and then I'll explain what it's doing:
    [Code=vb]Private Delegate Sub MyMethodDelegat e(ByVal ControlName As String, ByVal MyParam As String)

    Private Sub MyActualMethod( ByVal ControlName As String, ByVal MyParam As String)
    If Me.InvokeRequir ed Then
    Dim oDlg As New MyMethodDelegat e(AddressOf MyActualMethod)
    Me.Invoke(oDlg, ControlName, MyParam)
    Else
    Me.Controls(Con trolName).Text = MyParam
    End If
    End Sub

    Private Sub MyWorkerThread( ByVal Args As Object)
    MyActualMethod( "TextBox1", CType(Args, String))
    End Sub

    Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As System.EventArg s) Handles MyBase.Load
    Dim oThreadArgs As Object = "Hello World"
    Dim oThr As New Threading.Threa d(AddressOf MyWorkerThread)
    oThr.Start(oThr eadArgs)
    End Sub[/Code]

    Okay, in my form load, I'm spinning off a thread that references the method MyWorkerThread which posts a string that I've passed in my thread start mechanism into the text box.

    MyWorkerThread makes a call to the method called MyActualMethod which does a check to see if the form requires me to invoke (i.e. put this call on some call stack waiting for the form to synchronize threads) or if I can directly affect the change on my control. If you make a call to MyActualMethod from within your form directly, you will notice that when you step through the code, when you get into the MyActualMethod it always goes to the Else portion of your If statement. If you call it from your thread, it will always go through the If side of your statement a bunch of times before it goes to through the Else side...this is the system waiting for a safe slot to update the control.

    On to the Delegate routine. In the If side of your statement you will notice that we've instantiated the delegate just like we would have any other object or variable - Dim oDlg As New Delegate...

    The parameter we pass is a method address. What this is doing is running off behind the scenes is saying - "what memory address holds the block of code for the method with this name?" What we are effectively doing is this: We instantiate the delegate and tell it that when it is invoked, it must run the code contained within the method called MyActualMethod.

    When MyActualMethod is called from a thread, it may go through this loop several times before it finds a safe slot in which to actually write the value into the textbox...if it doesn't find a safe slot, it will keep invoking the delegate (which in effect, is calling itself).

    If you call MyActualMethod from the form itself, it never calls the delegate.

    Comment

    Working...