CNS 3260 C# .NET Software Development C# Threading CNS 3260 C# .NET Software Development C# Threading
Timers Timers execute a method at a given interval Three to choose from: System.Timers.Timer System.Threading.Timer System.Windows.Forms.Timer C# Threading
System.Timers.Timer Constructors: Members: Timer() Timer(double interval) Members: bool AutoReset bool Enabled double Interval in milliseconds Close() Start() Stop() Elapsed System.Timers.ElapsedEventHandler delegate C# Threading
System.Threading.Timer Constructor: Timer(TimerCallBack, object, long, long) Members: Change(long, long) TimerCallBack System.Threading.TimerCallBack(object state) cannot be changed once set C# Threading
System.Windows.Forms.Timer Has to be used with Windows Forms Members: bool Enabled int Interval Start() Stop() Tick System.EventHandler delegate (See Timers Demo) C# Threading
Threading: Advantages and Dangers Main Thread Reasons to use Threading Timers UI Responsiveness Multiple processors Dangers Race Conditions Deadlock Child Thread C# Threading
Spawning a new Thread IO Delegates System.Thread C# Threading
Threading IO FileStream.BeginRead(byte[] buffer, int offset, int numBytes, ASyncCallBack userCallBack, object stateObject) returns IAsyncResult object userCallBack delegate void ASyncCallBack(IAsyncResult ar) gets executed when the operation is finished FileStream.EndRead(IAsyncResult ar) Waits (blocks until the read is complete) returns (int) the number of bytes read C# Threading
Threading a Delegate (See DelegateThreading Demo) BeginInvoke(AsyncCallBack userCallBack, object stateObject) Returns an IAsyncResult object executes userCallBack when finished EndInvoke(IAsyncResult ar) Blocks until the delegate thread is finished Use AsyncResult object unless you have specific needs (See DelegateThreading Demo) C# Threading
IAsyncResult Members: AsyncResult object AsyncState AsynchWaitHandle User Object passed in AsynchWaitHandle Gets a thread handle that can be used to block CompletedSynchronously Indicates that the operation was fast enough that the system didn’t actually spawn a thread Use with IO operations IsCompleted Indicates whether the operation has completed AsyncResult object extend if you need specialized behavior C# Threading
System.Threading.Thread For more control over your threading situation Members: static CurrentThread static Sleep() Constructor Thread(ThreadStart start) IsBackground Priority ThreadState Abort() Interrupt() Join() Resume() Start() Suspend() C# Threading
Thread Static Members CurrentThread Sleep(int ticks) Returns a thread object for the current thread Sleep(int ticks) 1 tick == 1 ms Sleep(0) just releases the CPU Never use a busy-wait C# Threading
Thread Constructor Takes a ThreadStart delegate ThreadStart(void () target) Takes a method which returns void and has no params: void MyMethod() Thread begins execution when Start() is called Thread executes method passed to ThreadStart C# Threading
Thread Properties IsBackground Priority ThreadState get or set Once all foreground threads are finished, the runtime calls Abort on all background threads Default is false (or foreground) Priority ThreadPriority Enum Lowest, BelowNormal, Normal, AboveNormal, Highest ThreadState New Thread: ThreadState.Unstarted Started Thread: ThreadState.Running Sleep called: ThreadState.WaitSleepJoin Suspend called: ThreadState.Suspended See ThreadState Enumeration C# Threading
Thread Methods Start() Suspend() Resume() Interrupt() Begins execution of the thread Once a thread is finished, it cannot be restarted Suspend() Suspends the thread If the thread is already suspended, there is no effect Resume() Resumes a suspended thread Interrupt() Resumes a thread that is in a WaitSleepJoin state If the thread is not in WaitSleepJoin state it will be interrupted next time it is blocked C# Threading
Thread Methods (Continued) Abort() Attempts to abort the thread Throws a ThreadAbortException Join() Blocks the calling thread until the owning thread terminates C# Threading
Exceptions Between threads Must be handled in the thread it was thrown in Exceptions not handled in the thread are considered unhandled and will terminate that thread C# Threading
Threading Dangers volatile Fields Race Conditions Deadlock The CPU often stores variables in registers for optimization Other threads accessing that variable may not get the true value Race Conditions When multiple threads access the same memory A thread is interrupted while updating memory Solution: “lock” memory in a mutex, monitor, etc. Deadlock Two or more threads waiting on each other to release resources C# Threading
volatile Fields volatile fields may not be cached Types that may be volatile are: Any reference type Any pointer (unsafe code) sbyte, byte, short, ushort, int, uint An enum with one of the above base types Example: The Thread class also contains 2 static methods: VolatileRead() VolatileWrite() public volatile int myChangingInt = 0; C# Threading
Race Conditions Covered thoroughly in CNS 3060 Solved using a Mutex or Monitor Called Synchronization C# Threading
Synchronization Classes and Constructs lock keyword Mutex class Monitor class Interlocked class ReaderWriterLock class C# Threading
The lock Keyword Marks a statement as a critical section Is a Monitor underneath Example: lockObject must be a reference-type instance Typically you will lock on: ‘this’ locks the current instance typeof(MyClass) global lock for the given type A collection instance locks access to a specific collection lock(lockObject) { // critical section } C# Threading
The lock Mutex lock defines one Mutex for each object locked on Blocks until the current thread is finished (See Lock Demo) C# Threading
Mutex Class Stands for Mutual-Exclusion Blocking synchronization object WaitOne() Begins the critical section ReleaseMutex() Ends critical section Call ReleaseMutex() in a finally block C# Threading
Monitor Class (static) Enter(object obj) Begins a critical section Blocks if another thread has the same lock Exit(object obj) Ends a critical section Releases the lock TryEnter(object obj) Returns true if it obtains the lock Returns false if it can’t obtain the lock Avoids blocking if you can’t obtain the lock Wait(object obj) Releases the lock on an object and blocks until it reaquires the lock Pulse(object obj) Signals the next waiting thread that the lock may be free PulseAll(object obj) Signals all waiting threads that the lock may be free C# Threading
Interlocked Class (static) Provides atomic operations for variables CompareExchange(ref int dest, int source, int compare) Replaces dest with source if dest == compare Overloaded Exchange(ref int dest, int source) places source into dest returns the original value of dest Increment(ref int value) increments value Decrement(ref int value) decrements value C# Threading
ReaderWriterLock Class Allows a single writer or multiple readers Members: IsReaderLockHeld IsWriterLockHeld WriterSeqNum AcquireReaderLock() Increments the reader count AcquireWriterLock() Blocks until the lock is obtained ReleaseReaderLock() Decrements the reader count ReleaseWriterLock() Releases the writer lock ReleaseLock() Unconditionally releases the lock C# Threading
Deadlock Your job to avoid it object1 waiting for has Resource1 C# Threading
Windows Threading Windows disallows updating many GUI components across threads To update from the worker thread to the GUI thread InvokeRequired() Invoke(System.Delegate) (See Invoke Demo) C# Threading
Mediator Pattern Specialization GUI Thread Mediator Worker Thread subscribes Exposed Event fires when needed public FireEvent() C# Threading