|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
thread safetyCan anyone suggest a good (cheap) tool that will detect when a worker thread
calls directly in to a control on the UI thread? Thanks for your help Graham Try the following. I have not used it but I only read about it earlier
today. The idea sounds good: http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=3cba6 4b4-3765-49ba-8a05-11d247195e65 -- Show quoteHide quoteAjay Kalra [MVP - VC++] ajayka***@yahoo.com "Gravy" <Gr***@discussions.microsoft.com> wrote in message news:efpWsE01EHA.2012@TK2MSFTNGP15.phx.gbl... > Can anyone suggest a good (cheap) tool that will detect when a worker thread > calls directly in to a control on the UI thread? > > Thanks for your help > > Graham > > Thanks Ajay,
I truely did not think there was anything that could help me. This tool does raise a few questions for me though... I have tried to separate my UI layer such that I have UI classes (typically UserControls) and I have Controller classes that provide data to the UI classes from web services. All web service calls that a controller makes is asynchronous and I give it a callback to use to notify me of completion. This means on completion of the web service call I'm giving data to the UI class inside my callback and hence from a worker thread. Because this is a common occurance for my application I tried to make my UI classes thread aware. I did this by adding a call to InvokeRequired() and (if necessary) Invoke() at the top of all myl public methods, this means that I can call into me UI class from any thread and it would look after its own marshelling. However, there was a problem here. All public UserControl methods does not have the same sort of build in protection, so... One big question I have is; why don't the Windows forms controls do this for us? Does it really hurt performance? Isn't it as simple as say: public bool Focus() { if(InvokeRequired) Invoke(new MethodInvoker(Focus)); else { // usual code here } } Any insite would be really great. Thanks Graham Show quoteHide quote "Ajay Kalra" <ajayka***@yahoo.com> wrote in message news:OOgvnR11EHA.3708@TK2MSFTNGP14.phx.gbl... > Try the following. I have not used it but I only read about it earlier > today. The idea sounds good: > > http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=3cba6 > 4b4-3765-49ba-8a05-11d247195e65 > > -- > Ajay Kalra [MVP - VC++] > ajayka***@yahoo.com > > > "Gravy" <Gr***@discussions.microsoft.com> wrote in message > news:efpWsE01EHA.2012@TK2MSFTNGP15.phx.gbl... >> Can anyone suggest a good (cheap) tool that will detect when a worker > thread >> calls directly in to a control on the UI thread? >> >> Thanks for your help >> >> Graham >> >> > > I fully agree with your assessment about using InvokeRequired in the
control itself to make the control threadsafe. I personally fail to understand why this is not so to beginwith in Microsoft controls which are essentially nothing more than wrappers for controls in Comctl32.dll. I first saw this in Chris Sells's book on WinForms and have used it since then. This makes life easy for the clients as they dont have to worry about providing delegates each time they call controls from the worker thread. In addition, keeping the thread logic within a control makes it easy to remove/add worker thread. -------- Ajay Kalra ajayka***@yahoo.com Show quoteHide quote "Gravy" <Gr***@discussions.microsoft.com> wrote in message news:<uWrCoy31EHA.132@tk2msftngp13.phx.gbl>... > Thanks Ajay, > > I truely did not think there was anything that could help me. This tool does > raise a few questions for me though... > > I have tried to separate my UI layer such that I have UI classes (typically > UserControls) and I have Controller classes that provide data to the UI > classes from web services. All web service calls that a controller makes is > asynchronous and I give it a callback to use to notify me of completion. > This means on completion of the web service call I'm giving data to the UI > class inside my callback and hence from a worker thread. > > Because this is a common occurance for my application I tried to make my UI > classes thread aware. I did this by adding a call to InvokeRequired() and > (if necessary) Invoke() at the top of all myl public methods, this means > that I can call into me UI class from any thread and it would look after its > own marshelling. However, there was a problem here. All public UserControl > methods does not have the same sort of build in protection, so... > > One big question I have is; why don't the Windows forms controls do this for > us? Does it really hurt performance? Isn't it as simple as say: > > public bool Focus() > { > if(InvokeRequired) > Invoke(new MethodInvoker(Focus)); > else > { > // usual code here > } > } > > Any insite would be really great. > > Thanks > > Graham > > "Ajay Kalra" <ajayka***@yahoo.com> wrote in message > news:OOgvnR11EHA.3708@TK2MSFTNGP14.phx.gbl... > > Try the following. I have not used it but I only read about it earlier > > today. The idea sounds good: > > > > http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=3cba6 > > 4b4-3765-49ba-8a05-11d247195e65 > > > > -- > > Ajay Kalra [MVP - VC++] > > ajayka***@yahoo.com > > > > > > "Gravy" <Gr***@discussions.microsoft.com> wrote in message > > news:efpWsE01EHA.2012@TK2MSFTNGP15.phx.gbl... > >> Can anyone suggest a good (cheap) tool that will detect when a worker > thread > >> calls directly in to a control on the UI thread? > >> > >> Thanks for your help > >> > >> Graham > >> > >> > > > > Agreed Ajay, but the only problem I have found in doing this is any public
methods on the base class to my user control are not thread safe and unless I provide new implementations of them (for example Focus(), Enabled, Visable etc) the client experience is inconsistant. This was one reason I asked the newsgroup earlier if anyone knows of a wrapper class sfor Form, Control and or UserControl. I don't think anyone has done this though. Graham Show quoteHide quote "Ajay Kalra" <ajayka***@yahoo.com> wrote in message news:df39ee97.0412011117.3b82ecbd@posting.google.com... >I fully agree with your assessment about using InvokeRequired in the > control itself to make the control threadsafe. I personally fail to > understand why this is not so to beginwith in Microsoft controls which > are essentially nothing more than wrappers for controls in > Comctl32.dll. > > I first saw this in Chris Sells's book on WinForms and have used it > since then. This makes life easy for the clients as they dont have to > worry about providing delegates each time they call controls from the > worker thread. In addition, keeping the thread logic within a control > makes it easy to remove/add worker thread. > > -------- > Ajay Kalra > ajayka***@yahoo.com > > "Gravy" <Gr***@discussions.microsoft.com> wrote in message > news:<uWrCoy31EHA.132@tk2msftngp13.phx.gbl>... >> Thanks Ajay, >> >> I truely did not think there was anything that could help me. This tool >> does >> raise a few questions for me though... >> >> I have tried to separate my UI layer such that I have UI classes >> (typically >> UserControls) and I have Controller classes that provide data to the UI >> classes from web services. All web service calls that a controller makes >> is >> asynchronous and I give it a callback to use to notify me of completion. >> This means on completion of the web service call I'm giving data to the >> UI >> class inside my callback and hence from a worker thread. >> >> Because this is a common occurance for my application I tried to make my >> UI >> classes thread aware. I did this by adding a call to InvokeRequired() and >> (if necessary) Invoke() at the top of all myl public methods, this means >> that I can call into me UI class from any thread and it would look after >> its >> own marshelling. However, there was a problem here. All public >> UserControl >> methods does not have the same sort of build in protection, so... >> >> One big question I have is; why don't the Windows forms controls do this >> for >> us? Does it really hurt performance? Isn't it as simple as say: >> >> public bool Focus() >> { >> if(InvokeRequired) >> Invoke(new MethodInvoker(Focus)); >> else >> { >> // usual code here >> } >> } >> >> Any insite would be really great. >> >> Thanks >> >> Graham >> >> "Ajay Kalra" <ajayka***@yahoo.com> wrote in message >> news:OOgvnR11EHA.3708@TK2MSFTNGP14.phx.gbl... >> > Try the following. I have not used it but I only read about it earlier >> > today. The idea sounds good: >> > >> > http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=3cba6 >> > 4b4-3765-49ba-8a05-11d247195e65 >> > >> > -- >> > Ajay Kalra [MVP - VC++] >> > ajayka***@yahoo.com >> > >> > >> > "Gravy" <Gr***@discussions.microsoft.com> wrote in message >> > news:efpWsE01EHA.2012@TK2MSFTNGP15.phx.gbl... >> >> Can anyone suggest a good (cheap) tool that will detect when a worker >> thread >> >> calls directly in to a control on the UI thread? >> >> >> >> Thanks for your help >> >> >> >> Graham >> >> >> >> >> > >> > Few points:
1. Its really slow (switching thread and creating expensive objects such as mutex) 2. If you want to do a bunch of updates you would want to switch manually 3. This one is probably the biggest: Invoke implies synchronization which can lead to deadlocks. 4. Because of 3 you might want to do BeginInvoke but it changes things a lot. Therefore regardless of choice made by Control designers someone would not be happy. 5. True that most controls (but not all) are wrappers of user32 and comctl32 controls but those are also not thread safe. The truth is user32 in general is not very thread safe. There are APIs which have thread affinity for example DestroyWindow Gravy why does this tool raise any questions you didn't have before? I wrote the tool but it's not really production quality so if you have questions let me know. Show quoteHide quote "Ajay Kalra" <ajayka***@yahoo.com> wrote in message news:df39ee97.0412011117.3b82ecbd@posting.google.com... >I fully agree with your assessment about using InvokeRequired in the > control itself to make the control threadsafe. I personally fail to > understand why this is not so to beginwith in Microsoft controls which > are essentially nothing more than wrappers for controls in > Comctl32.dll. > > I first saw this in Chris Sells's book on WinForms and have used it > since then. This makes life easy for the clients as they dont have to > worry about providing delegates each time they call controls from the > worker thread. In addition, keeping the thread logic within a control > makes it easy to remove/add worker thread. > > -------- > Ajay Kalra > ajayka***@yahoo.com > > "Gravy" <Gr***@discussions.microsoft.com> wrote in message > news:<uWrCoy31EHA.132@tk2msftngp13.phx.gbl>... >> Thanks Ajay, >> >> I truely did not think there was anything that could help me. This tool >> does >> raise a few questions for me though... >> >> I have tried to separate my UI layer such that I have UI classes >> (typically >> UserControls) and I have Controller classes that provide data to the UI >> classes from web services. All web service calls that a controller makes >> is >> asynchronous and I give it a callback to use to notify me of completion. >> This means on completion of the web service call I'm giving data to the >> UI >> class inside my callback and hence from a worker thread. >> >> Because this is a common occurance for my application I tried to make my >> UI >> classes thread aware. I did this by adding a call to InvokeRequired() and >> (if necessary) Invoke() at the top of all myl public methods, this means >> that I can call into me UI class from any thread and it would look after >> its >> own marshelling. However, there was a problem here. All public >> UserControl >> methods does not have the same sort of build in protection, so... >> >> One big question I have is; why don't the Windows forms controls do this >> for >> us? Does it really hurt performance? Isn't it as simple as say: >> >> public bool Focus() >> { >> if(InvokeRequired) >> Invoke(new MethodInvoker(Focus)); >> else >> { >> // usual code here >> } >> } >> >> Any insite would be really great. >> >> Thanks >> >> Graham >> >> "Ajay Kalra" <ajayka***@yahoo.com> wrote in message >> news:OOgvnR11EHA.3708@TK2MSFTNGP14.phx.gbl... >> > Try the following. I have not used it but I only read about it earlier >> > today. The idea sounds good: >> > >> > http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=3cba6 >> > 4b4-3765-49ba-8a05-11d247195e65 >> > >> > -- >> > Ajay Kalra [MVP - VC++] >> > ajayka***@yahoo.com >> > >> > >> > "Gravy" <Gr***@discussions.microsoft.com> wrote in message >> > news:efpWsE01EHA.2012@TK2MSFTNGP15.phx.gbl... >> >> Can anyone suggest a good (cheap) tool that will detect when a worker >> thread >> >> calls directly in to a control on the UI thread? >> >> >> >> Thanks for your help >> >> >> >> Graham >> >> >> >> >> > >> > Dmitriy,
the thing that got me thinking about all this thread safe control stuff again was highlighted by GThreadCop. I was getting a lot of vialotion in one particular method. To cut a long storey short the violations were happening because my controller class (non UI) was dealing with interfaces that the UI forms / controls implement. Now, in order for my controller to switch to the UI thread I had to add a property on my interface with returned the underlying control, but in order to get the underlying control I had to call in to a UI control from a worker thread (the controller). Anyway after using the GThreadCop a bit more I see that I can ignore this violation anyway. BTW, thanks for the points below. I thought there had to be some reason for a windows form or control not doing this. Show quoteHide quote "Dmitriy Zaslavskiy" <dimka***@yahoo.com> wrote in message news:e3UOq6B2EHA.1860@TK2MSFTNGP15.phx.gbl... > Few points: > 1. Its really slow (switching thread and creating expensive objects such > as mutex) > 2. If you want to do a bunch of updates you would want to switch manually > 3. This one is probably the biggest: Invoke implies synchronization which > can lead to deadlocks. > 4. Because of 3 you might want to do BeginInvoke but it changes things a > lot. > Therefore regardless of choice made by Control designers someone would not > be happy. > 5. True that most controls (but not all) are wrappers of user32 and > comctl32 controls but those are also not thread safe. > The truth is user32 in general is not very thread safe. There are APIs > which have thread affinity for example DestroyWindow > > Gravy why does this tool raise any questions you didn't have before? > I wrote the tool but it's not really production quality so if you have > questions let me know. > > > "Ajay Kalra" <ajayka***@yahoo.com> wrote in message > news:df39ee97.0412011117.3b82ecbd@posting.google.com... >>I fully agree with your assessment about using InvokeRequired in the >> control itself to make the control threadsafe. I personally fail to >> understand why this is not so to beginwith in Microsoft controls which >> are essentially nothing more than wrappers for controls in >> Comctl32.dll. >> >> I first saw this in Chris Sells's book on WinForms and have used it >> since then. This makes life easy for the clients as they dont have to >> worry about providing delegates each time they call controls from the >> worker thread. In addition, keeping the thread logic within a control >> makes it easy to remove/add worker thread. >> >> -------- >> Ajay Kalra >> ajayka***@yahoo.com >> >> "Gravy" <Gr***@discussions.microsoft.com> wrote in message >> news:<uWrCoy31EHA.132@tk2msftngp13.phx.gbl>... >>> Thanks Ajay, >>> >>> I truely did not think there was anything that could help me. This tool >>> does >>> raise a few questions for me though... >>> >>> I have tried to separate my UI layer such that I have UI classes >>> (typically >>> UserControls) and I have Controller classes that provide data to the UI >>> classes from web services. All web service calls that a controller makes >>> is >>> asynchronous and I give it a callback to use to notify me of completion. >>> This means on completion of the web service call I'm giving data to the >>> UI >>> class inside my callback and hence from a worker thread. >>> >>> Because this is a common occurance for my application I tried to make my >>> UI >>> classes thread aware. I did this by adding a call to InvokeRequired() >>> and >>> (if necessary) Invoke() at the top of all myl public methods, this means >>> that I can call into me UI class from any thread and it would look after >>> its >>> own marshelling. However, there was a problem here. All public >>> UserControl >>> methods does not have the same sort of build in protection, so... >>> >>> One big question I have is; why don't the Windows forms controls do this >>> for >>> us? Does it really hurt performance? Isn't it as simple as say: >>> >>> public bool Focus() >>> { >>> if(InvokeRequired) >>> Invoke(new MethodInvoker(Focus)); >>> else >>> { >>> // usual code here >>> } >>> } >>> >>> Any insite would be really great. >>> >>> Thanks >>> >>> Graham >>> >>> "Ajay Kalra" <ajayka***@yahoo.com> wrote in message >>> news:OOgvnR11EHA.3708@TK2MSFTNGP14.phx.gbl... >>> > Try the following. I have not used it but I only read about it earlier >>> > today. The idea sounds good: >>> > >>> > http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=3cba6 >>> > 4b4-3765-49ba-8a05-11d247195e65 >>> > >>> > -- >>> > Ajay Kalra [MVP - VC++] >>> > ajayka***@yahoo.com >>> > >>> > >>> > "Gravy" <Gr***@discussions.microsoft.com> wrote in message >>> > news:efpWsE01EHA.2012@TK2MSFTNGP15.phx.gbl... >>> >> Can anyone suggest a good (cheap) tool that will detect when a worker >>> thread >>> >> calls directly in to a control on the UI thread? >>> >> >>> >> Thanks for your help >>> >> >>> >> Graham >>> >> >>> >> >>> > >>> > > > Check out the comments on
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=3cba64b4-3765-49ba-8a05-11d247195e65 on how to tell GThreadCop to ignore known OK functions Show quoteHide quote "Gravy" <Gr***@discussions.microsoft.com> wrote in message news:eBOYChN2EHA.2804@TK2MSFTNGP15.phx.gbl... > Dmitriy, > > the thing that got me thinking about all this thread safe control stuff > again was highlighted by GThreadCop. I was getting a lot of vialotion in > one particular method. To cut a long storey short the violations were > happening because my controller class (non UI) was dealing with interfaces > that the UI forms / controls implement. Now, in order for my controller to > switch to the UI thread I had to add a property on my interface with > returned the underlying control, but in order to get the underlying > control I had to call in to a UI control from a worker thread (the > controller). Anyway after using the GThreadCop a bit more I see that I can > ignore this violation anyway. > > BTW, thanks for the points below. I thought there had to be some reason > for a windows form or control not doing this. > > > "Dmitriy Zaslavskiy" <dimka***@yahoo.com> wrote in message > news:e3UOq6B2EHA.1860@TK2MSFTNGP15.phx.gbl... >> Few points: >> 1. Its really slow (switching thread and creating expensive objects such >> as mutex) >> 2. If you want to do a bunch of updates you would want to switch manually >> 3. This one is probably the biggest: Invoke implies synchronization which >> can lead to deadlocks. >> 4. Because of 3 you might want to do BeginInvoke but it changes things a >> lot. >> Therefore regardless of choice made by Control designers someone would >> not be happy. >> 5. True that most controls (but not all) are wrappers of user32 and >> comctl32 controls but those are also not thread safe. >> The truth is user32 in general is not very thread safe. There are APIs >> which have thread affinity for example DestroyWindow >> >> Gravy why does this tool raise any questions you didn't have before? >> I wrote the tool but it's not really production quality so if you have >> questions let me know. >> >> >> "Ajay Kalra" <ajayka***@yahoo.com> wrote in message >> news:df39ee97.0412011117.3b82ecbd@posting.google.com... >>>I fully agree with your assessment about using InvokeRequired in the >>> control itself to make the control threadsafe. I personally fail to >>> understand why this is not so to beginwith in Microsoft controls which >>> are essentially nothing more than wrappers for controls in >>> Comctl32.dll. >>> >>> I first saw this in Chris Sells's book on WinForms and have used it >>> since then. This makes life easy for the clients as they dont have to >>> worry about providing delegates each time they call controls from the >>> worker thread. In addition, keeping the thread logic within a control >>> makes it easy to remove/add worker thread. >>> >>> -------- >>> Ajay Kalra >>> ajayka***@yahoo.com >>> >>> "Gravy" <Gr***@discussions.microsoft.com> wrote in message >>> news:<uWrCoy31EHA.132@tk2msftngp13.phx.gbl>... >>>> Thanks Ajay, >>>> >>>> I truely did not think there was anything that could help me. This tool >>>> does >>>> raise a few questions for me though... >>>> >>>> I have tried to separate my UI layer such that I have UI classes >>>> (typically >>>> UserControls) and I have Controller classes that provide data to the UI >>>> classes from web services. All web service calls that a controller >>>> makes is >>>> asynchronous and I give it a callback to use to notify me of >>>> completion. >>>> This means on completion of the web service call I'm giving data to the >>>> UI >>>> class inside my callback and hence from a worker thread. >>>> >>>> Because this is a common occurance for my application I tried to make >>>> my UI >>>> classes thread aware. I did this by adding a call to InvokeRequired() >>>> and >>>> (if necessary) Invoke() at the top of all myl public methods, this >>>> means >>>> that I can call into me UI class from any thread and it would look >>>> after its >>>> own marshelling. However, there was a problem here. All public >>>> UserControl >>>> methods does not have the same sort of build in protection, so... >>>> >>>> One big question I have is; why don't the Windows forms controls do >>>> this for >>>> us? Does it really hurt performance? Isn't it as simple as say: >>>> >>>> public bool Focus() >>>> { >>>> if(InvokeRequired) >>>> Invoke(new MethodInvoker(Focus)); >>>> else >>>> { >>>> // usual code here >>>> } >>>> } >>>> >>>> Any insite would be really great. >>>> >>>> Thanks >>>> >>>> Graham >>>> >>>> "Ajay Kalra" <ajayka***@yahoo.com> wrote in message >>>> news:OOgvnR11EHA.3708@TK2MSFTNGP14.phx.gbl... >>>> > Try the following. I have not used it but I only read about it >>>> > earlier >>>> > today. The idea sounds good: >>>> > >>>> > http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=3cba6 >>>> > 4b4-3765-49ba-8a05-11d247195e65 >>>> > >>>> > -- >>>> > Ajay Kalra [MVP - VC++] >>>> > ajayka***@yahoo.com >>>> > >>>> > >>>> > "Gravy" <Gr***@discussions.microsoft.com> wrote in message >>>> > news:efpWsE01EHA.2012@TK2MSFTNGP15.phx.gbl... >>>> >> Can anyone suggest a good (cheap) tool that will detect when a >>>> >> worker >>>> thread >>>> >> calls directly in to a control on the UI thread? >>>> >> >>>> >> Thanks for your help >>>> >> >>>> >> Graham >>>> >> >>>> >> >>>> > >>>> > >> >> > >
Other interesting topics
Transparent control
find process by processname Deployed simple C#.NET single form application to Windows server 2003 and the form will not display, How to simply load a freeekin bitmap from a resource? DateTime Bound to TextBox Creating VS Studio like control creating VS Studio like controls Post-Mortem Debugging How to print AxWebBrowser control? prevent Multi line select on DataGrid? |
|||||||||||||||||||||||