Can threads access global variables??
-
Tuesday, September 01, 2009 4:41 PMHi 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.
All Replies
-
Tuesday, September 01, 2009 4:43 PMI means what is the use of .increment and why is it made??
A candle loses nothing by lighting another candle. -
Tuesday, September 01, 2009 8:06 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 10:39 PMTo 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 11:16 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 -
Wednesday, September 02, 2009 12:56 AM
When accessing a global variable, some problems may occur.
Look at this codePublic 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 Classif 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 2:12 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 10:47 AMHi 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 2:23 PMMaybe 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 4:12 PMTry 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 5:31 PMjust 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 CrazypennieMicrosoft Community Contributor Wednesday, September 02, 2009 6:21 PM
-
Wednesday, September 02, 2009 5:46 PMYou 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 8:09 PMI tried thr read writer lock claas but no luck
A candle loses nothing by lighting another candle. -
Wednesday, September 02, 2009 8:32 PMHi,
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 9:02 PMyou 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:04 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:47 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
-
Thursday, September 03, 2009 11:15 AMnice one Silver_Gates !!
www.dsmyth.net | www.dsmyth.net/wiki

