Title: 'NET Mobile Application Development Concurrency in Distributed Clients
1.NET Mobile Application DevelopmentConcurrency
in Distributed Clients
2Introduction
- Concurrency occurs in all distributed systems
- Controlling concurrency is essentially to
developing scalable, correct distributed
applications - In this session and the next we will consider
- Multi-threading and concurrency
- Concurrency in distributed clients
- Concurrency control mechanisms
3Concurrency in Distributed Applications
- Distributed applications are inherently
concurrent - Services have to deal with multiple simultaneous
clients in a scalable manner - Clients may need to perform multiple simultaneous
activities - Accept user input and use services
- Concurrency needs to be used and managed
correctly to avoid - Performance penalties
- Incorrect operation and sequencing of activities
4Concurrency in Distributed Clients
- Concurrency is mainly used in distributed clients
to overcome latencies resulting from distributed
interactions - This has several benefits
- Increased client performance
- Client can perform other activities / processing
whilst remote interactions proceed - Increased client responsiveness and improved user
experience - User interface does not freeze when remote
interactions or lengthy computations occur - Application responds to user input in a timely
manner
5Multithreading
- Thread
- An independent unit of program execution
- Multithreaded program
- Multiple threads execute simultaneously
- Threads multiplexed onto available CPUs using
timeslicing - Context switch incurs (minor) overhead
- Threads exist in the same process and share
common address space - Multithreading
- can improve performance only when there is an
operation with some latency - the longer the delay, the greater the potential
performance benefit from using threads - will not improve performance if threads are
competing for finite (e.g. CPU) resources
multithreading will actually result in worse
performance
6Threading Issues
- Multithreading can improve performance
- Multithreading will introduce
- additional complexity
- unusual errors that are difficult to detect,
replicate and debug - additional overhead OS must manage all the
threads - Getting threading right is difficult need to
- use synchronization and locking to ensure correct
interleaving of thread operations and
interactions - balance potential improvements from threading
against additional overheads (number of threads) - avoid deadlock, livelock, race conditions, etc
caused by incorrect / insufficient / too much
synchronization
7Threading in .NET
- Can use threads in .NET by
- Using .NET types with built-in threading support
- Types that support asynchronous operation (i.e.
has Begin? and End? methods) - Windows forms types through the Invoke() method
- Manually creating and manipulating threads using
the System.Threading.Thread type
8Using Asynchronous Delegates
- A delegate is
- a type-safe pointer to a method (function
pointer) - an instance of the Delegate type
- Delegate type has two important methods
- BeginInvoke()
- invokes the method referred to by the delegate on
a separate thread - immediately returns an IAsyncResult instance and
allows calling thread to continue - EndInvoke()
- allows retrieval of results from a method invoked
earlier using BeginInvoke() - needs to be given IAsyncResult instance returned
by BeginInvoke()
9Asynchronous Delegate Example
- delegate int MyDelegate(int i, int j)
- class Program
- public static void Main()
- Maths m new Maths()
- // Create the delegate - note that BeginInvoke
always takes 2 extra parameters - MyDelegate dlgt new MyDelegate(m.Add)
- // Asynchronosly invoke it
- IAsyncResult iar dlgt.BeginInvoke(2, 2, null,
null) - // Do something else whilst call progresses
- // Wait for async method to complete and
retrieve the results - int result dlgt.EndInvoke(iar)
-
-
- class Maths
- Criticisms
- EndInvoke() call blocks if method invoked by
delegate not yet completed - Can poll for completion using the IAsyncResult
instance - Neither option is good
10Using Callbacks
- Callback
- method called when an asynchronously invoked
delegate completes its operation - Callbacks
- eliminate inefficient polling
- simplify coding
- Callback method
- signature must match System.AsyncCallback
delegate type - AsyncCallback instance referencing desired
callback method must be passed to BeginInvoke() - callback is passed an IAsyncResult object when it
is invoked - use this to call EndInvoke() and retrieve results
11Asynchronous Callback Example
- delegate int MyDelegate(int i, int j)
- class Program
- static MyDelegate dlgt
- public static void Main()
- Maths m new Maths()
- AsyncCallback cdlgt new AsyncCallback(MyCallbac
k) - dlgt new MyDelegate(m.Add)
- // Penultimate BeginInvoke() parameter is
callback delegate - IAsyncResult iar dlgt.BeginInvoke(2, 2, cdlgt,
null) - Console.ReadLine() // Do something else
-
- public static void MyCallback(IAsyncResult
iar) - int result dlgt.EndInvoke(iar) // Use
IAsyncResult instance to retrieve the results -
-
- NOTE
- Callback method executes on yet another thread
12Advantages of Asynchronous Invocation
- Implicitly using threads by using asynchronous
invocation has several advantages - environment takes care of creating and managing
all threads for us - no need for explicit concurrency control
operations - improves performance by enabling long-running
tasks to be started without stalling application - Asynchronous invocation not suitable for
- code which needs to communicate between threads
- applications which need to prioritize threads
- this requires manual thread creation
13Creating .NET Threads
- Threads are created by
- declaring a method which will be the body of the
thread - must be of return type void and accept no
parameters - can call any other methods
- creating a ThreadStart delegate instance which
refers to this method - creating a new Thread object, passing it the
delegate - calling Thread.Start()
- System.Threading.Thread
- is the primary type used for managing threads
- allows threads to be created, started, stopped,
suspended, resumed, joined, delayed, etc
14Custom Threading Example
- class Program
-
- public static void Main()
- // Create the threads
- Thread tA new Thread(new ThreadStart(TaskA))
- Thread tB new Thread(new ThreadStart(TaskB))
- tA.Start() // Start the threads
- tB.Start()
- Console.ReadLine() // Pause until user
presses key -
- private static void TaskA()
- for (int i 0 i lt 10 i)
- Console.WriteLine("Task A at "i)
- WasteTime(1000)
-
- private static void TaskB()
- for (int i 0 i lt 10 i)
15Thread Priorities
- Threads are selected for execution based on their
priority - highest priority execute first, lowest priority
last - All threads created equally with default normal
priority - priority can be adjusted via Thread.Priority
property - five relative priority levels supported
- Lowest, Below Normal, Normal, Above Normal,
Highest - Setting thread priorities correctly is important
- giving a thread too high a priority can lead to
starvation of other threads
16Thread Priority Example
- class Program
-
- public static void Main()
- Thread tA new Thread(new ThreadStart(TaskA))
- Thread tB new Thread(new ThreadStart(TaskB))
-
- tA.Priority ThreadPriority.AboveNormal
tB.Priority ThreadPriority.Normal - tA.Start() tB.Start() // Start the threads
- Console.ReadLine() // Pause until user
presses key -
- private static void TaskA()
- for (int i 0 i lt 10 i)
- Console.WriteLine("Task A at "i)
- WasteTime(1)
-
- private static void TaskB()
- for (int i 0 i lt 10 i)
17Threaded Clients
- Any operation which will take a long time to
complete or adversely affect application
responsiveness is a good candidate for executing
on a separate thread - e.g. Windows Media Player 9
- Info Center View takes time to retrieve data from
the Internet - executing this on separate thread from user
interface allows user to control playback in the
meantime - when data is returned from Internet, UI can be
appropriately updated
18User Interfaces in .NET Threaded Clients
- Windows Forms controls in a .NET application
- are not thread safe
- can only be safely operated upon by the thread
which owns them - Consider the Windows Media Player example with a
thread which fetches data from the Internet. This
thread - is separate from the UI thread
- should not update the applications UI as it is
not the owner of the UI controls
19Win Forms and Threading
- Windows.Forms.Control base class provides an
Invoke() method which is passed a delegate to
another method - Delegate must be of type MethodInvoker
- Delegated method acts as a callback used to
update the relevant control - Calling Invoke() causes the delegated update
method to be safely invoked on the User Interface
thread which owns the control
20WinForms Threading Example
- Simple Form application with two threads
- UI thread created by Application.Run()
- separate thread used to periodically increments
counter - button controls operation of counter thread
- UIUpdater() displays latest count value in
lblCount Label - Counter thread
- creates delegate to UIUpdater()
- calls lblCount.Invoke() with this delegate each
time it wishes to update the count value in the UI
21Concurrency Control
- Two key aspects to concurrency control
- Mutual exclusion
- Preventing object / resource from being accessed
by more than one thread at once - Needed to prevent corruption of state in presence
of multiple client updates - Implemented through locking
- Synchronization
- Imposes order on interleaving of operations of
multiple threads (usually for correctness) - Implemented using semaphores, condition variables
or monitors
22Condition Synchronization
- Needed when a thread wishes to perform an
operation which can only sensibly(safely) be
performed if another thread has itself taken some
other action or is in some defined state - Example A bounded buffer has 2 condition
synchronization - producer thread must not attempt to put data in
buffer if it is full - consumer thread must not attempt to get data from
buffer if it is empty - Is mutual exclusion necessary?
23Locks and Mutual Exclusion
- Critical Section - a sequence of statements that
appear to execute indivisibly - Mutual Exclusion - synchronization required to
protect a critical section - Locks - implement mutual exclusion and guard
critical sections - Code construct which marks a critical section of
code that must be executed under mutual exclusion
24Locking
- In an OO environment, every object has an
associated lock - Lock construct specifies the object on which the
lock should be obtained - First thread to execute the lock statement will
be granted the lock and can execute protected
section of code - Whilst first thread has the lock, any other
threads executing the lock statement will block
until lock is released. Waiting threads will then
compete for the lock.
25Example Locking in C
- int Withdraw(int amount)
-
- lock (this)
-
- if (balance gt amount)
- Console.WriteLine("Balance before Withdrawal
" balance) - Console.WriteLine("Amount to Withdraw
-" amount) - balance balance - amount
- Console.WriteLine("Balance after
Withdrawal " balance) - return amount
-
- else
- return 0 // transaction rejected
-
-
26Locking - Disadvantages
- Locking is essential to preventing conflicting
updates but can adversely affect performance - If scope of lock is too great
- forces some threads to wait
- decreases potential concurrency and throughput /
performance - If scope of lock is too small
- forces reacquisition of locks, leading increased
lock contention and reduced throughput /
performance - can result in difficult-to-debug race conditions
27Advanced Locking
- Mutual exclusion
- not needed if all threads are reading values
- needed if at least one thread is writing values
- ReaderWriter lock
- allows concurrent read access for multiple
threads, or - write access for a single thread
- uses separate locks for readers and writers
clients must specify which lock they want
28Advanced Locking Example
- ReaderWriterLock rwl new ReaderWriterLock()
- void ReadFromResource(int timeOut)
- try
- rwl.AcquireReaderLock(timeOut)
- try
- / Safe for this thread to read from
- // the shared resource.
-
- finally
- // Ensure that the lock is released.
- rwl.ReleaseReaderLock()
-
-
- catch (ApplicationException)
- // The reader request timed out.
-
-
void WriteToResource(int timeOut) try
rwl.AcquireWriterLock(timeOut) try
// It is safe for this thread to read
// or write from the shared
resource. finally //
Ensure that the lock is released.
rwl.ReleaseWriterLock()
catch (ApplicationException) // The
writer lock request timed out.
29Monitors
- Monitor
- code construct that provides both mutual
exclusion and condition synchronization - acts like a smart lock
- Thread enters the monitor and attempts to acquire
lock - if successful, thread executes under mutual
exclusion thread frees lock when finished - if unsuccessful, thread blocks until monitor is
available
30Monitors Condition Synchronisation
- When inside a monitor, condition variables can be
used - Thread can Wait() on condition variable
- thread blocks and releases lock, freeing monitor
to other threads - when condition becomes true, thread unblocks,
reacquires lock and executes under mutual
exclusion - Thread can Signal() a condition variable
- notifies waiting threads that condition is true
- teleases lock, freeing monitor to other threads
31.NET Monitors Example
- public class MyClass
-
- private object x
- public void DoSomething()
- Monitor.Enter(x)
- try
- // Code that needs protected by the
monitor. - // Monitor.Wait and Monitor.Pulse can be
- // used in here
-
- finally
- // Ensure that you exit Monitor.
- Monitor.Exit(x)
-
32Common Concurrency Problems
- Two common problems
- Deadlock
- A situation where two or more threads are unable
to proceed because each is waiting for the others
to do something - Avoid by
- always acquiring / releasing locks in the same
order - ensuring that all Wait()s have a matching
Signal() - Race Conditions
- Anomalous behaviour due to unexpected critical
dependence on the relative ordering of operations - Can occur is scope of locks is too small and some
code left outside critical sections - These problems are
- Easy to unwittingly introduce
- Difficult to detect and remove
33Summary
- In this session we have discussed
- The role of concurrency in distributed clients
- Multi-threading and thread management in .NET
- Asynchronous invocation and callback
- Locks, monitors and performance
- Alternative thread coordination mechanisms
34Reading and Resources
- Reading
- Coulouris, Dollimore Kindberg, Distributed
Systems Concepts and Design, 3rd Edition,
Addison-Wesley, 2001 - Chapter 12, pp 465 514
- MacDonald, Microsoft .NET Distributed
Applications Integrating XML Web Services and
.NET Remoting, Microsoft Press, 2003 - Chapter 6, pp 175 220
-