In a class, static
fields are the most error-prone parts of the application. They need to be
handled gracefully since they represent a shared resource.
One and only one
instance is created for a static field. That’s why, any change on a static
field directly affects all code blocks accessing to it.
Inherently, sometimes
classes may need some fields to act like a static variable just for a certain execution context. Actually, here I mean “Executing
Thread” while saying “Execution Context”. In other saying, some code may need
to protect a static field and create its own copy in its local storage. Thus,
any change caused by a thread will not affect the static value that is used by
another thread.
Let’s make it
clear by a real-life sample:
Suppose, you have
many pages in your UI tier. Any changes that is performed on a page by a user,
is sent to your Logic tier to be processed. This change is sent to your logic
tier as “Message” objects.
( Here we use “Command Pattern” which is one of GoF Design Patterns. Please refer to Command Pattern at: http://www.dofactory.com/Patterns/PatternCommand.aspx)
( Here we use “Command Pattern” which is one of GoF Design Patterns. Please refer to Command Pattern at: http://www.dofactory.com/Patterns/PatternCommand.aspx)
When the message is
received by logic tier, the User that causes the change must be kept in a
static field. Because all the remaining functions that will perform and
finalize change message will need the User for logging, approval mechanisms,
etc.
Similarly, Database
handle must be created. Because many codes that run after receiving message are
going to need Database connection.
You cannot declare these fields as totally static because it will cause to get incorrect values that is updated by another context. (For example, when the User A and User B perform update in UI tier at the same time, the update that is caused by User A may be logged as if it is updated by User B)
You cannot declare these fields as totally static because it will cause to get incorrect values that is updated by another context. (For example, when the User A and User B perform update in UI tier at the same time, the update that is caused by User A may be logged as if it is updated by User B)
The main necessity here is that; User and
Database Handle objects need to be static, but only for the thread that is executing
message.
In .NET, there is an extremely convenient and
easy-to-use solution to handle this problem. The answer is : ThreadStatic attribute.
C# Code:
Here, when the CustomerDetailsUpdateMessage is received by logic tier, the thread that is executing the message will create its own copy of static UserName and DbHandle fields. So that any other message executing concurrently will not cause any update on the value that accessed by current thread.