This is a much better example. You shouldn't lock this and should lock a private lock object instead. You shouldn't use volatile since you have more than one variable that may change at a time. The properties should also lock the same lock object because you don't want a property to execute in the middle of your locked AddVistaTx method and get an invalid set of data.
The lock will definitely hurt performance, but you really don't have a choice. And worrying about lack of inlining (or other performance characteristics in general) is mostly useless until you can actually have something to performance test. Worrying about one minor CIL instruction (and yes, if lock injects a finally it will execute even with a return in there) should be the least of your concerns. Adam.. > -----Original Message----- > From: Discussion of advanced .NET topics. [mailto:ADVANCED- > [EMAIL PROTECTED] On Behalf Of Eddie Lascu > Sent: Thursday, August 10, 2006 5:27 PM > To: [email protected] > Subject: Re: [ADVANCED-DOTNET] Multithread-safe classes > > Hi Gregory, > > I tried to simplify the class and by doing that, my problem mandates a > simpler solution. Here is a more accurate version of the class: > > public sealed class CCTxBatch > { > public CCTxBatch(string strTerminalId) > { > strTerminalId_ = strTerminalId; > } > > public int VisaTransactionsCount > { > get > { > return nVisaTxCount_; > } > } > public double VisaTransactionsAmount > { > get > { > return dVisaTxTotalAmount_; > } > } > // next ones here > > public void ResetCountsAndTotals() > { > nVisaTxCount_ = 0; > dVisaTxTotalAmount_ = 0.0; > > nAmexTxCount_ = 0; > dAmexTxTotalAmount_ = 0.0; > > nMCardTxCount_ = 0; > dMCardTxTotalAmount_ = 0.0; > } > > public void AddVisaTx( double dAmount ) > ( > nVisaTxCount_++; > dVisaTxTotalAmount_ += dAmount; > } > > public void AddAmexTx( double dAmount ) > ( > nAmexTxCount_++; > dAmexTxTotalAmount_ += dAmount; > } > > public void AddMCardTx( double dAmount ) > ( > nMCardTxCount_++; > dMCardTxTotalAmount_ += dAmount; > } > > int nVisaTxCount_; > double dVisaTxTotalAmount_; > > int nAmexTxCount_; > double dAmexTxTotalAmount_; > > int nMCardTxCount_; > double dMCardTxTotalAmount_; > > string strTerminalId_; > } > > I want to have a single lock for all members, because there are yet other > methods that can change multiple pairs. The methods do not return > anything, > so I can have all the code inside the method wrapped into a lock(this). I > was curios about the properties. > > Regards, > Eddie > > > > -----Original Message----- > From: Discussion of advanced .NET topics. > [mailto:[EMAIL PROTECTED] Behalf Of gregory young > Sent: Thursday, August 10, 2006 6:07 PM > To: [email protected] > Subject: Re: [ADVANCED-DOTNET] Multithread-safe classes > > > Yes your code will still work fine. There are however some huge > differences between this code and the original. > > 1) inlining will not be performed since you have put the lock in (this > will result in a (relatively) significant performance hit compared to > the original) > 2) In some cases you will have a memory barrier > 3) You don't need a critical section in this case (see explanation below) > 4) You should be locking on a private lock object as opposed to > locking on "this" > > > An alternative which you should consider would be > > public sealed class MyClass > { > public MyClass(string strValue) > { > strMyField_ = strValue; > } > > public string MyField > { > get > { > return strMyField_; > } > } > > volatile string strMyField_; > } > > This will inline properly and offers nearly identical behavior as your > first example without the overhead you are introducing with a critical > section. This can only be used on items that are the size of a > reference or smaller. The reason you can do this is that anything the > size of a reference or smaller is assured to be changed in an atomic > fashion where you would not need to actually define a critical > section. If the size is over the size of a reference you would then > need to lock in order to insure only one thread at a time is dealing > with the data. > > > > On 8/10/06, Eddie Lascu <[EMAIL PROTECTED]> wrote: > > I want to make my class multithread safe. What's the effect of writing > > something like this: > > > > public sealed class MyClass > > { > > public MyClass(string strValue) > > { > > strMyField_ = strValue; > > } > > > > public string MyField > > { > > get > > { > > lock(this) > > { > > return strMyFieldId_; > > } > > } > > } > > > > string strMyField_; > > } > > > > I know "lock" injects the "finally" block into the CIL, but is that > executed > > if the return is before? > > > > =================================== > > This list is hosted by DevelopMentor(r) http://www.develop.com > > > > View archives and manage your subscription(s) at > http://discuss.develop.com > > > > > -- > If knowledge can create problems, it is not through ignorance that we > can solve them. > > Isaac Asimov > > =================================== > This list is hosted by DevelopMentorR http://www.develop.com > > View archives and manage your subscription(s) at > http://discuss.develop.com > > =================================== > This list is hosted by DevelopMentorR http://www.develop.com > > View archives and manage your subscription(s) at > http://discuss.develop.com =================================== This list is hosted by DevelopMentorĀ® http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com
