locked
Can threads access global variables??

    Question

  • Hi I need to find out if threads can access global variables and if they can write to it ... without using delegates .. When i tried it  ,, sometimes you could use em and sometimes errors occur anyways i am not still sure ??/ and what does the .increment do to shared variables which are used in threads??
    A candle loses nothing by lighting another candle.
    Tuesday, September 01, 2009 4:41 PM

Answers

  • Solved the problem using manual reset event
    thanks for your help guys really appreciate it.



    A candle loses nothing by lighting another candle.
    • Marked as answer by Silver_Gates Wednesday, September 02, 2009 9:47 PM
    Wednesday, September 02, 2009 9:47 PM

All replies

  • I means what is the use of .increment and why is it made??

    A candle loses nothing by lighting another candle.
    Tuesday, September 01, 2009 4:43 PM
  • You can access all global variables, but you cannot call methods of another thread except for the four thread safe methods: Invoke, BeginInvoke, EndInvoke and CreateGraphics. When you access properties, you actually call a hidden method and you are in principle not allowed to do that in another thread. For example, myControl.BackColor = Colors.Green looks like you set a simple variable, but it is really a shorthand for myControl.Set_BackColor(Colors.Green), that is, a method call. In practice, .Net allows you to set some properties in another thread, but not all. Unfortunately, it is not defned anywhere which properties you are allowed to access.
    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.
    • Proposed as answer by Rudedog2MVP Wednesday, September 02, 2009 6:02 PM
    Tuesday, September 01, 2009 8:06 PM
  • To summarize it. I could access global variables in threads . The following code will work then I believe. do let me know


    Public Class form1
    Dim T1 as Thread
    dim AVariable as string

            Private Sub Sample()
             msgbox AVariable            'Will display "Hello"
            AVariable = "Bye"            'Will work 
            mgbox (AVariable & textbox1.text) //?? will this work??
            textbox1.text = "Good" 'I know this wont work u need to use delegates
            end sub
          
            Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            AVariable = "Hello"
            Textbox1.text = "Hello"  'Textbox control placed on form1
            T1=new Thread Addressof(Sample)
            T1.start    
            end sub

    end class

    could u also add some more example points to above code if there are any??



    A candle loses nothing by lighting another candle.
    Tuesday, September 01, 2009 10:39 PM
  • I Really dont understand what are you trying to do in your code, but Your code wont work like that ,

    BECAUSE THE VARIABLES FROM THREAD CLASS ARE SHARED IT MEANS YOU CAN USE IT DIRECTLY

    BUT IF I am not wrong you can try something like this

    Imports System.Threading.Thread
    Imports System.Threading
    
    Public Class Form1
    
        Dim AVariable As String
    
        Private Sub Sample()
            MsgBox(AVariable)            'Will display "Hello"
            AVariable = "Bye"            'Will work  
            MsgBox(AVariable & TextBox1.Text)
            TextBox1.Text = "Good" 'I know this wont work u need to use delegates
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            AVariable = "Hello"
            TextBox1.Text = "Hello"  'Textbox control placed on form1
    
            Sample()
    
            Thread.Sleep(1000)
        End Sub
    
    End Class


    the variables always has access from other classes , only if the variables are private or Dim dreclared , this variables wont have access from other classes.


    the global variables are declared as Shared Type ....



    Regards

    Marca como respuesta a la mejor contestacion que el usuario Responda....Melvin
    Tuesday, September 01, 2009 11:16 PM


  • When accessing a global variable, some problems may occur.

    Look at this code

    Public Class form1
        Dim T1 = New Threading.Thread(AddressOf Sample)
        Dim AVariable As String
    
        Private Sub Sample()
    
            MsgBox(AVariable)            
    
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            AVariable = "Hello"
            T1.start()
            AVariable = "Bye"
        End Sub
    
    End Class
    

    if you notice, at the time you start your new thread, AVariable had the value "Hello" but just after the thread was started, the value was changed to "Bye"

    What value will the msgbox show ??

    In fact, the answer is impredictible, it depend if the thread T1 reads the variable before the value get changed or not.

    This is a thread race situation

    something else may happen, T1 may try to read AVAriable in the same time that the UI thread is updating the value. this may result in some unwanted thread behaviour

    This is a thread collision

    to avoid these situations a thread can create a lock to force the other thread(s) to wait for the variable(s) to be updated before reading them

     





     

    Wednesday, September 02, 2009 12:56 AM
  • @Crazypennie
    oh that explains a lot  so is that why we use SyncLock Me to lock the variables before writing??
    thanks

    A candle loses nothing by lighting another candle.
    Wednesday, September 02, 2009 2:12 AM
  • Hi this question directly relates to this issue which i am trying to solve. My server imports multiple files form the client. using the following code
    Now when one file is downloading the server goes in a loop till a global variable is triggered by a thread. the code is:

     Private Sub cmdDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDownload.Click
            Dim My_Array() As String
            Dim My_String As String
            Dim Selected As Integer
            Dim i As Integer
            Dim mybyte() As Byte
            My_String = TreeView1.SelectedNode.Text.ToString()
            My_Array = Split(My_String, "#")
            Selected = Val(My_Array(1)) - 1
            'Determine Which Client is Selected    
            For i = 0 To ListSelected.Items.Count - 1
                InProgress = True
                TextConsole.AppendText(vbCrLf & "Importing" & ListSelected.Items.Item(i).ToString)
                mybyte = Encoding.ASCII.GetBytes("#Import#" & ListSelected.Items.Item(i).ToString)
                client(Selected).GetStream.Write(mybyte, 0, mybyte.Length)
                Do
                    Console.WriteLine(InProgress) 
                Loop While (InProgress = True) --------- now when the file finishes downloading InProgress = False but the above             
                                                                        line says that it is True and it continously remain true and program remains in loop
            Next i
        End Sub


    Why isnt the thread changing Inprogress variable to false it closes the file and displays Transfer complete in textbox (via delegate) so why isnt it changin the value of the variable ?? is there a work around for this??


    A candle loses nothing by lighting another candle.
    Wednesday, September 02, 2009 10:47 AM
  • Maybe because your computer is so busy infinitely writing to the console that the other thread can't set InProgress to false!

    Anyway, first look at where your InProgress variable is declared.
    Wednesday, September 02, 2009 2:23 PM
  • Try searching the MSDN library for "APM Callback" and "IAsyncResult". 
    It is a mechanism already setup in the .NET FCL to allow threads to communicate through events.


    I already gave you an example in this thread .
    Mark the best replies as answers. "Fooling computers since 1971."
    • Edited by Rudedog2MVP Wednesday, September 02, 2009 6:05 PM
    Wednesday, September 02, 2009 4:12 PM
  • just after the line :

    Console.WriteLine(InProgress) 

    Add:

    Threading.Thread.Sleep(100)


    and try it again, this may work.

    What may happen is that the Do/Loop may be looping over a hundread thousand time per seconde, The console however can not write this fast, so all these WriteLine that were send to the console are now buffered. So the console will keep writing "True" until the buffer is empty, which may take long.


    By having your thread sleeping 100 milliseconds at each loop, only 10 times per seconde the console will be written and it should keep up.
    • Edited by Crazypennie Wednesday, September 02, 2009 6:21 PM
    Wednesday, September 02, 2009 5:31 PM
  • You may use ReaderWriterLock Class . This is a special class for reading a variable from different places.

    Hope it helps

    Cheers

    Waleed El-Badry ,Teaching Assistant, Faculty of Engineering , Misr University for Science & Technology
    Wednesday, September 02, 2009 5:46 PM
  • I tried thr read writer lock claas but no luck

    A candle loses nothing by lighting another candle.
    Wednesday, September 02, 2009 8:09 PM
  • Hi,

    Ok I have read all the above and I think this is just the wrong approach. Global variables and threading means your need to be very careful of whats accessing when and locking and well basically I think what your looking to do can be done in a much easier way.

    "when one file is downloading the server goes in a loop till a global variable is triggered by a thread"

    You want the downloading thread to trigger the server directly and not through a global variable.


    rudedog posted about "Asynchronous Processing Model Callback" and "IAsyncResult", this is the best way to do this. No global variable!! Thats the problem; the global variable. Remove the global variable and all your troubles will go with it.


    Another option, maybe a little easier, is to use the BackgroundWorker component. This will work just as well in a console application as it does on a windows application.


    www.dsmyth.net | www.dsmyth.net/wiki
    Wednesday, September 02, 2009 8:32 PM
  • you can also take a look at this Link it provide a Examples from Threading.Thrad

    http://msdn.microsoft.com/en-us/library/system.threading.thread(VS.96).aspx






    Regards.

    Melvin.
    Marca como respuesta a la mejor contestacion que el usuario Responda....Melvin
    Wednesday, September 02, 2009 9:02 PM
  • Hi again,

    Here is an example that uses a global variable. The thing is though the thread does NOT set the global variable, so no locks are needed!! the thread only downloads the file. The downloading thread notifies the main thread through the OnFileDownloadComplete event. BTW I haven't tested this code but it should be pretty close.


    Module Module1
    
        Dim web As New Net.WebClient
        Dim files As New Stack(Of Uri)
        Dim complete As Boolean = False
    
        Sub Main()
            files.Push(New Uri("http://www.site.com/File1.txt"))
            files.Push(New Uri("http://www.site.com/File2.txt"))
    
            AddHandler web.DownloadFileCompleted, AddressOf OnFileDownloadComplete
            DownloadNextFile()
    
            'OK OK granted, using a global variable here, but it isn't set by a thread (aaaah see)
            While Not complete
                ' dusnufink
            End While
    
        End Sub
    
        Public Sub DownloadNextFile()
            If files.Count > 0 Then
                Dim uri As Uri = files.Pop
                web.DownloadFileAsync(uri, "C:\" & uri.Segments.Last())  'thread only downloads the file
            Else
                complete = True
            End If
        End Sub
    
        Public Sub OnFileDownloadComplete(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
            DownloadNextFile()
        End Sub
    
    End Module

    www.dsmyth.net | www.dsmyth.net/wiki
    Wednesday, September 02, 2009 9:04 PM
  • Solved the problem using manual reset event
    thanks for your help guys really appreciate it.



    A candle loses nothing by lighting another candle.
    • Marked as answer by Silver_Gates Wednesday, September 02, 2009 9:47 PM
    Wednesday, September 02, 2009 9:47 PM
  • nice one Silver_Gates !!
    www.dsmyth.net | www.dsmyth.net/wiki
    Thursday, September 03, 2009 11:15 AM