Hi, Charles if variable is control - answer is you must use Invoke. If it is some object non-related to UI, you can simply set it using lock statement. Lock - because even if it is private variable if you have more than 1 thread you might have synchronization problems. You might want to check lock statement and volatile modifier in .Net documentation to get more details. HTH Alex [quoted text, click to view] "Charles Law" <blank@nowhere.com> wrote in message news:OJn7yH2PEHA.1276@TK2MSFTNGP11.phx.gbl... > I have a user control created on the main thread. Let's say, for arguments > sake, that it has a single property that maintains a private variable. If I > want to set that property from a worker thread, do I need to use > UserControl1.Invoke to set it, or can I just set it? After all, it is only > changing a private variable. > > TIA > > Charles > >
----- Charles Law wrote: ---- After all, it is only changing a private variable Famous last words
I have a user control created on the main thread. Let's say, for arguments sake, that it has a single property that maintains a private variable. If I want to set that property from a worker thread, do I need to use UserControl1.Invoke to set it, or can I just set it? After all, it is only changing a private variable. TIA Charles
If you ignore thread-safety issues, the answer is no, you don't need to use Invoke to update private fields from another thread. If you are actually updating the screen, or perform an operation which directly or indirectly calls an API that is thread sensitive, then you need to use Invoke. [quoted text, click to view] "Charles Law" <blank@nowhere.com> wrote in message news:OJn7yH2PEHA.1276@TK2MSFTNGP11.phx.gbl... > I have a user control created on the main thread. Let's say, for arguments > sake, that it has a single property that maintains a private variable. If I > want to set that property from a worker thread, do I need to use > UserControl1.Invoke to set it, or can I just set it? After all, it is only > changing a private variable. > > TIA > > Charles > >
I didn't examine your code so I am not commenting on the specifics of what you've done. The basic rule is actually quite simple: if setting a value causes an operation to occur that is thread sensitive, then you must ensure that you set the value while running on the correct thread. If all it is doing is changing a simple field and there are no side effects, then it should be safe to do so. If the value you set is actually property setter, then you are doing more then changing the value of a field, you are running code of unknown complexity and which is potentially unbounded. Unless you are sure that the code in the property setter will itself take care of threading issues, you should do so before you call it. For example, if changing the property causes events to get fired, then you could have a lot of problems if this occurred on the wrong thread. [quoted text, click to view] "Charles Law" <blank@nowhere.com> wrote in message news:O$BV9oBQEHA.2420@TK2MSFTNGP10.phx.gbl... > Hi David > > Thanks for the response. I have elaborated in my reply to Alex. Do you think > this changes anything? I don't want to ignore thread safety issues. > > Charles > > > "David Levine" <noSpamdlevineNNTP2@wi.rr.com> wrote in message > news:%23E9AyO%23PEHA.3748@TK2MSFTNGP09.phx.gbl... > > If you ignore thread-safety issues, the answer is no, you don't need to > use > > Invoke to update private fields from another thread. If you are actually > > updating the screen, or perform an operation which directly or indirectly > > calls an API that is thread sensitive, then you need to use Invoke. > > > > "Charles Law" <blank@nowhere.com> wrote in message > > news:OJn7yH2PEHA.1276@TK2MSFTNGP11.phx.gbl... > > > I have a user control created on the main thread. Let's say, for > arguments > > > sake, that it has a single property that maintains a private variable. > If > > I > > > want to set that property from a worker thread, do I need to use > > > UserControl1.Invoke to set it, or can I just set it? After all, it is > only > > > changing a private variable. > > > > > > TIA > > > > > > Charles > > > > > > > > > > > >
The thread saftey issues of your private field aside, the only time you need to use the Main Thread (UserControl1.Invoke) is for anything that will update the UI. Its all about the painting. If 2 threads do something that cause the form to repaint itself, it will take a big crap on you. If this private member you are updating causes an event, the event is executed with that thread. If that event changes a status bar on the form, then you gotta move it over to the control's main thread. I suggest in your private member, you use Invoke to fire the event from the main thread. -- Eric Marvets Principal Consultant the bang project <shameless self promotion> Email sales@bangproject.com for Information on Our Architecture and Mentoring Services </shameless self promotion>
Hi Alex I'll come clean. I fibbed. I am updating a control, but I use Invoke for that. What I actually have is a user control (UserControl1) that combines a progress bar and a track bar. The track bar is used to set a value for the progress bar, and when this happens the control raises an event to say that it has happened. This user control is placed on another user control (UserControl2), which has a property 'Position'. This parent user control is then placed on a form. The form also has a Position property. The worker (background) thread can change the position as well, by Form1.Position = 50 The form level Position property contains UserControl2.Position = Value The UserControl2 Position property contains UserControl1.Position = Value Finally, the UserControl1 Position property has If ProgressBar1.InvokeRequired Then ' Use delegate and Invoke to set value Else ' Set property directly End If As you will see, I have only used Invoke at the final stage, even though, if I test UserControl2.InvokeRequired for example, at the higher level, I find that it is True. Does this mean that I should have, at the form level If UserControl2.InvokeRequired Then ' Use delegate and Invoke to set value Else ' Set property directly UserControl1.Position = Value End If or am I ok with what I have? Charles [quoted text, click to view] "AlexS" <salexru2000NO@SPAMsympaticoPLEASE.ca> wrote in message news:%239P2gV2PEHA.3232@TK2MSFTNGP11.phx.gbl... > Hi, Charles > > if variable is control - answer is you must use Invoke. If it is some object > non-related to UI, you can simply set it using lock statement. Lock - > because even if it is private variable if you have more than 1 thread you > might have synchronization problems. > > You might want to check lock statement and volatile modifier in .Net > documentation to get more details. > > HTH > Alex > > "Charles Law" <blank@nowhere.com> wrote in message > news:OJn7yH2PEHA.1276@TK2MSFTNGP11.phx.gbl... > > I have a user control created on the main thread. Let's say, for arguments > > sake, that it has a single property that maintains a private variable. If > I > > want to set that property from a worker thread, do I need to use > > UserControl1.Invoke to set it, or can I just set it? After all, it is only > > changing a private variable. > > > > TIA > > > > Charles > > > > > >
Hi David Thanks for the response. I have elaborated in my reply to Alex. Do you think this changes anything? I don't want to ignore thread safety issues. Charles [quoted text, click to view] "David Levine" <noSpamdlevineNNTP2@wi.rr.com> wrote in message news:%23E9AyO%23PEHA.3748@TK2MSFTNGP09.phx.gbl... > If you ignore thread-safety issues, the answer is no, you don't need to use > Invoke to update private fields from another thread. If you are actually > updating the screen, or perform an operation which directly or indirectly > calls an API that is thread sensitive, then you need to use Invoke. > > "Charles Law" <blank@nowhere.com> wrote in message > news:OJn7yH2PEHA.1276@TK2MSFTNGP11.phx.gbl... > > I have a user control created on the main thread. Let's say, for arguments > > sake, that it has a single property that maintains a private variable. If > I > > want to set that property from a worker thread, do I need to use > > UserControl1.Invoke to set it, or can I just set it? After all, it is only > > changing a private variable. > > > > TIA > > > > Charles > > > > > >
Hi David Thanks for the rule. It has got me thinking. [quoted text, click to view] > For example, if changing the property > causes events to get fired, then you could have a lot of problems if this > occurred on the wrong thread.
You may have hit on something here. I'm away to check the code to see what is actually happening. Charles [quoted text, click to view] "David Levine" <noSpamdlevineNNTP2@wi.rr.com> wrote in message news:%23rPyEbCQEHA.904@TK2MSFTNGP12.phx.gbl... > I didn't examine your code so I am not commenting on the specifics of what > you've done. The basic rule is actually quite simple: if setting a value > causes an operation to occur that is thread sensitive, then you must ensure > that you set the value while running on the correct thread. If all it is > doing is changing a simple field and there are no side effects, then it > should be safe to do so. > > If the value you set is actually property setter, then you are doing more > then changing the value of a field, you are running code of unknown > complexity and which is potentially unbounded. Unless you are sure that the > code in the property setter will itself take care of threading issues, you > should do so before you call it. For example, if changing the property > causes events to get fired, then you could have a lot of problems if this > occurred on the wrong thread. > > > "Charles Law" <blank@nowhere.com> wrote in message > news:O$BV9oBQEHA.2420@TK2MSFTNGP10.phx.gbl... > > Hi David > > > > Thanks for the response. I have elaborated in my reply to Alex. Do you > think > > this changes anything? I don't want to ignore thread safety issues. > > > > Charles > > > > > > "David Levine" <noSpamdlevineNNTP2@wi.rr.com> wrote in message > > news:%23E9AyO%23PEHA.3748@TK2MSFTNGP09.phx.gbl... > > > If you ignore thread-safety issues, the answer is no, you don't need to > > use > > > Invoke to update private fields from another thread. If you are actually > > > updating the screen, or perform an operation which directly or > indirectly > > > calls an API that is thread sensitive, then you need to use Invoke. > > > > > > "Charles Law" <blank@nowhere.com> wrote in message > > > news:OJn7yH2PEHA.1276@TK2MSFTNGP11.phx.gbl... > > > > I have a user control created on the main thread. Let's say, for > > arguments > > > > sake, that it has a single property that maintains a private variable. > > If > > > I > > > > want to set that property from a worker thread, do I need to use > > > > UserControl1.Invoke to set it, or can I just set it? After all, it is > > only > > > > changing a private variable. > > > > > > > > TIA > > > > > > > > Charles > > > > > > > > > > > > > > > > > > > >
Yes. Thread saftey has a number of its own issues, but ignore those for now. Until Longhorn, WinForms is built on top of the Win32 API, and there all messages sent to the Win32 API need to be done with the owner thread, or for us the main thread in the application. It owns all the controls. In .NET 2.0, and exception is raised anytime this is not done. For now, I use the rule of thumb, that if it does anything remotly graphical with the UI, I use Invoke. -- Eric Marvets Principal Consultant the bang project <shameless self promotion> Email sales@bangproject.com for Information on Our Architecture and Mentoring Services </shameless self promotion>
Hi Eric You mention the painting issue, and now you've got me thinking. I use Invoke for controls, but I don't use it for 'painting' as such. I have code in the OnPaint override, and I read that the graphics object passed in was thread safe, so I use stuff like DrawRectangle without using Invoke. Are you saying that I need to use Invoke even when using the graphics method to draw things? Charles [quoted text, click to view] "Eric Marvets" <ericm@bangproject.com> wrote in message news:eB$bttDQEHA.1432@TK2MSFTNGP09.phx.gbl... > The thread saftey issues of your private field aside, the only time you need > to use the Main Thread (UserControl1.Invoke) is for anything that will > update the UI. Its all about the painting. If 2 threads do something that > cause the form to repaint itself, it will take a big crap on you. If this > private member you are updating causes an event, the event is executed with > that thread. If that event changes a status bar on the form, then you gotta > move it over to the control's main thread. > > I suggest in your private member, you use Invoke to fire the event from the > main thread. > > > -- > Eric Marvets > Principal Consultant > > the bang project > > <shameless self promotion> > > Email sales@bangproject.com for Information on Our Architecture and > Mentoring Services > > </shameless self promotion> > >
Don't see what you're looking for? Try a search.
|