This is a discussion on Threading in C# .Net 2005 : within the C# Programming forums, part of the Software Development category; Hi Sathish.... Any object visible to each of the partaking threads can be used as a synchronizing object, subject to ...
| |||||||
| Register | FAQ | Members List | Calendar | Mark Forums Read |
| |||
| Hi Sathish.... Any object visible to each of the partaking threads can be used as a synchronizing object, subject to one hard rule: it must be a reference type. It’s also highly recommended that the synchronizing object be privately scoped to the class (i.e. a private instance field) to prevent an unintentional interaction from external code locking the same object. Subject to these rules, the synchronizing object can double as the object it's protecting, such as with the list field below: class ThreadSafe() { List <string> list = new List <string>(); void Test() { lock (list) { list.Add ("Item 1"); ... A dedicated field is commonly used (such as locker, in the example prior), because it allows precise control over the scope and granularity of the lock. Using the object or type itself as a synchronization object, i.e.: lock (this) { ... } or: lock (typeof (Widget)) { ... } // For protecting access to statics is discouraged because it potentially offers public scope to the synchronization object. thnx... |
| Sponsored Links |
| |||
| Hi Sathish... A thread can repeatedly lock the same object, either via multiple calls to Monitor.Enter, or via nested lock statements. The object is then unlocked when a corresponding number of Monitor.Exit statements have executed, or the outermost lock statement has exited. This allows for the most natural semantics when one method calls another as follows: static object x = new object(); static void Main() { lock (x) { Console.WriteLine ("I have the lock"); Nest(); Console.WriteLine ("I still have the lock"); } Here the lock is released. } static void Nest() { lock (x) { ... } Released the lock? Not quite! } A thread can block only on the first, or outermost lock. thnx... |
| |||
| Hi Sathish... As a basic rule, any field accessible to multiple threads should be read and written within a lock. Even in the simplest case – an assignment operation on a single field – one must consider synchronization. In the following class, neither the Increment nor the Assign method is threadsafe: class ThreadUnsafe { static int x; static void Increment() { x++; } static void Assign() { x = 123; } } Here are thread-safe versions of Increment and Assign: class ThreadUnsafe { static object locker = new object(); static int x; static void Increment() { lock (locker) x++; } static void Assign() { lock (locker) x = 123; } } As an alternative to locking, one can use a non-blocking synchronization construct in these simple situations. This is discussed in Part 4 (along with the reasons that such statements require synchronization). i hope this will help you.... thnx.... |
| |||
| Hi Sathish... Locking itself is very fast: a lock is typically obtained in tens of nanoseconds assuming no blocking. If blocking occurs, the consequential task-switching moves the overhead closer to the microseconds-region, although it may be milliseconds before the thread's actually rescheduled. This, in turn, is dwarfed by the hours of overhead – or overtime – that can result from not locking when you should have! Locking can have adverse effects if improperly used – impoverished concurrency, deadlocks and lock races. Impoverished concurrency occurs when too much code is placed in a lock statement, causing other threads to block unnecessarily. A deadlock is when two threads each wait for a lock held by the other, and so neither can proceed. A lock race happens when it’s possible for either of two threads to obtain a lock first, the program breaking if the “wrong” thread wins. Deadlocks are most commonly a syndrome of too many synchronizing objects. A good rule is to start on the side of having fewer objects on which to lock, increasing the locking granularity when a plausible scenario involving excessive blocking arises. thnx... |
| |||
| Hi Sathish... Calling Interrupt on a blocked thread forcibly releases it, throwing a ThreadInterruptedException, as follows: class Program { static void Main() { Thread t = new Thread (delegate() { try { Thread.Sleep (Timeout.Infinite); } catch (ThreadInterruptedException) { Console.Write ("Forcibly "); } Console.WriteLine ("Woken!"); }); t.Start(); t.Interrupt(); } } Forcibly Woken! Interrupting a thread only releases it from its current (or next) wait: it does not cause the thread to end (unless, of course, the ThreadInterruptedException is unhandled!) If Interrupt is called on a thread that’s not blocked, the thread continues executing until it next blocks, at which point a ThreadInterruptedException is thrown. This avoids the need for the following test: if ((worker.ThreadState & ThreadState.WaitSleepJoin) > 0) worker.Interrupt(); which is not thread-safe because of the possibility of being preempted in between the if statement and worker.Interrupt. Interrupting a thread arbitrarily is dangerous, however, because any framework or third-party methods in the calling stack could unexpectedly receive the interrupt rather than your intended code. All it would take is for the thread to block briefly on a simple lock or synchronization resource, and any pending interruption would kick in. If the method wasn't designed to be interrupted (with appropriate cleanup code in finally blocks) objects could be left in an unusable state, or resources incompletely released. 24 Interrupting a thread is safe when you know exactly where the thread is. Later we cover signaling constructs, which provide just such a means. thnx... |
| |||
| Hi Sathish... A blocked thread can also be forcibly released via its Abort method. This has an effect similar to calling Interrupt, except that a ThreadAbortException is thrown instead of a ThreadInterruptedException. Furthermore, the exception will be re-thrown at the end of the catch block (in an attempt to terminate the thread for good) unless Thread.ResetAbort is called within the catch block. In the interim, the thread has a ThreadState of AbortRequested. The big difference, though, between Interrupt and Abort, is what happens when it's called on a thread that is not blocked. While Interrupt waits until the thread next blocks before doing anything, Abort throws an exception on the thread right where it's executing – maybe not even in your code. Aborting a non-blocked thread can have significant consequences, the details of which are explored in the later section "Aborting Threads". thnx... |
| |||
| Hi Sathish... One can query a thread's execution status via its ThreadState property. Figure 1 shows one "layer" of the ThreadState enumeration. ThreadState is horribly designed, in that it combines three "layers" of state using bitwise flags, the members within each layer being themselves mutually exclusive. Here are all three layers: · the running / blocking / aborting status (as shown in Figure 1) · the background/foreground status (ThreadState.Background) · the progress towards suspension via the deprecated Suspend method (ThreadState.SuspendRequested and ThreadState.Suspended) 25 In total then, ThreadState is a bitwise combination of zero or one members from each layer! thnx... |
![]() |
| Thread Tools | |
| Display Modes | |
| |
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| ASP.net threading issue when populating a listbox | $enthil | ASP and ASP.NET Programming | 6 | 11-04-2007 11:24 PM |
| Threading in VB.Net Tips | S.Vinothkumar | VB.NET Programming | 16 | 10-30-2007 07:55 AM |
| How to implement threading in VB.Net? | amansundar | VB.NET Programming | 2 | 10-30-2007 07:41 AM |
| I Cannot access SQL 2005 integrated services after installing SQL-2005..? | theone | Database Support | 1 | 07-27-2007 01:12 AM |
| what is the threading model used for ASP.Net? | mobilegeek | ASP and ASP.NET Programming | 1 | 07-21-2007 01:48 AM |