-
Aug 21st, 2012, 05:31 AM
#1
Thread Starter
New Member
Problem with controls, forms and thread concurrency
Hi.
Im doing a program in vb .net 2010 that consist in various forms with custom controls in them. The main form declares a shared system timer and some variables, shared too.
When the main form loads I initiate the timer with an interval of 1 second and modify in the elapsed event some of these variables. For example I have a boolean that alternatively changes from true to false.
The thing is that i want to synchronize all the controls in the others forms with this global timer so in the Load of the control I had a handler for the elapsed event of the global timer, as it's the only way I know of how to do it.
With this I can for example make the images in all the controls blink at the same time, synchronized, thanks to the shared boolean of the main form. In the main form I modify it in the elapsed event and in each control I assign the visibility to the image based on this boolean in the elapsed handler of the global shared timer.
The problem with this, as you can imagine, is the concurrent use of the shared variables. If I read, for example, the boolean in one of the controls while it's being modified, it generates an exception.
I have been investigating trying to find how to solve this problem. I have seen about delegates, the SyncLock instruction and some other more, but I don't know how to apply them. From what I can remember of concurrent programming, I should need an exclusive lock where I modify the boolean and shared lock whenever I read that boolean, but im somewhat new in .Net and im a little lost. Does anyone has any piece of advice for me?
Thanks in advance
Regards
Last edited by Leucaruth; Aug 21st, 2012 at 06:33 AM.
-
Aug 21st, 2012, 06:45 AM
#2
Re: Problem with controls, forms and thread concurrency
I would suggest that you're going about this in very much the wrong way. As far as I can tell, the point of all this is to synchronise the behaviour of several UI elements. Any change to the UI must occur on the UI thread so why are we talking about synchronising multiple threads at all? You appear to be using a System.Timers.Timer, which is the wrong choice. You should be using a System.Windows.Forms.Timer. The Timers.Timer can raise its Elapsed event on a thread pool thread, which is an advantage in some cases. In this situation you would need marshal a method call back to the UI thread to update the UI anyway, so what's the benefit of starting on a secondary thread in the first place?
Here's how I would approach it. Firstly, I would create a custom Timer class that inherits the Windows.Forms.Timer class:
vb.net Code:
Public Class BlinkTimer Inherits System.Windows.Forms.Timer Private _blinkState As Boolean Public ReadOnly Property BlinkState As Boolean Get Return _blinkState End Get End Property Protected Overrides Sub OnTick(e As EventArgs) 'Flip the state. _blinkState = Not _blinkState 'Raise the Tick event. MyBase.OnTick(e) End Sub End Class
You now don't need the flag in the form because it's incorporated into the Timer. Now, if each of your controls depends on a Timer then that Timer should be internal to those controls. If you're creating UserControls then you're already creating a custom class. If you're using other standard controls, e.g. Button, just do as I did above for Timer, i.e. inherit the class and add the required functionality:
vb.net Code:
Public Class BlinkButton Inherits System.Windows.Forms.Button Private WithEvents _timer As BlinkTimer Public Property Timer As BlinkTimer Get Return _timer End Get Set(value As BlinkTimer) _timer = value End Set End Property Private Sub _timer_Tick(sender As Object, e As System.EventArgs) Handles _timer.Tick If _timer.BlinkState Then 'Blink state is on. Else 'Blink state is off. End If End Sub End Class
So now, you can add an instance of the BlinkTimer class to your form in the designer or in code and, from there, assign it to the Timer property of each control. You can handle the Tick event of the BlinkTimer in the form or not as needed:
vb.net Code:
Public Class Form1 Private WithEvents _timer As BlinkTimer Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load BlinkButton1.Timer = _timer End Sub Private Sub _timer_Tick(sender As Object, e As System.EventArgs) Handles _timer.Tick If _timer.BlinkState Then 'Blink state is on. Else 'Blink state is off. End If End Sub End Class
That's it. You treat the BlinkTimer the same way to treat a regular WinForms Timer. It raises its Tick event and it gets handled in the form and/or each control. You know that each and every control will get the same value for BlinkState because it was set before the event was raised and every event handler will be executed before it can be raised again.
-
Aug 22nd, 2012, 01:47 AM
#3
Thread Starter
New Member
Re: Problem with controls, forms and thread concurrency
Thanks for the answer, jmcilhinney
While it's true that one of the points of the timer is to synchronize the behaviour of those elements, I have to use them to gather and set data in a time basis. I think I can accomplish all the problems I had with this, I'll comment soon if it works well.
Regards
-
Aug 27th, 2012, 07:08 AM
#4
Thread Starter
New Member
Re: Problem with controls, forms and thread concurrency
Hi again.
I have been testing the solution you gave me and I don't have anymore threading errors but I have found some problem that I don't know how to solve.
The program must run in low end pc's (like atoms 1,6gh with 1gb ram), and in a form can find more than 100 controls that can be blinking at the same time. When I tested this, I saw that the blinking isn't synchronous in all the controls, but it seems like a flow, I mean there is a very little delay between controls when they "blink" that doesn't give a feeling of being changing simultaneously.
The controls are very simple and the images too, so it shouldn't take too much time to load them. I have been searching information about the system.form.timer and I think it's something about how it works, but i'm not sure.
Any idea of how to solve this? If neccesary I can upload a vid of how this works and the code too :S
Thanks in advance
-
Aug 27th, 2012, 11:33 AM
#5
Re: Problem with controls, forms and thread concurrency
You're gonna need a bigger computer!
There really is no cure for this but total parallel processing (for which you'll need very, very deep pockets!). Your commands have to run sequentially and the more there are the longer it takes. With 10 controls on a fast computer it's not going to be noticeable but with 100 controls on a slow one it inevitably will be. I suggest you give some thought as to whether you really need this behaviour for anything other than purely cosmetic reasons.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|