'NET Async Programming Demystified - PowerPoint PPT Presentation

1 / 38
About This Presentation
Title:

'NET Async Programming Demystified

Description:

... also that you not use Thread.Abort(). This is a nasty way to interrupt a thread. ... MSDN Library http://msdn.microsoft.com/library/ Newsgroups ... – PowerPoint PPT presentation

Number of Views:230
Avg rating:3.0/5.0
Slides: 39
Provided by: keith150
Category:

less

Transcript and Presenter's Notes

Title: 'NET Async Programming Demystified


1
.NET Async Programming Demystified

Keith Rome, MCSD MCAD MCDBA keith_at_mindfusioncorp.c
om http//www.mindfusioncorp.com/weblog/
2
What is Async Programming?
  • A method of executing long-running processes.

3
When to use it?
  • For Non-UI Applications / Components
  • When you need to obtain better utilization of
    processing resources.
  • For UI Applications / Components
  • When you need to achieve a more responsive user
    interface.

4
When to NOT use it?
  • If you cannot establish a realistic need.
  • If the risk of introducing new bugs is not
    tolerable.
  • Async programming is more complex and introduces
    greater exposure to potential bugs.
  • If you dont know what you are getting into.
  • Because you think its cool.

5
Types of Async Processing
  • From simplest to most complex
  • Faking it
  • External Processes
  • Queuing
  • Multithreading
  • Each has its strengths and weaknesses choose
    the one thats best for your situation.

6
Faking Async Processing
  • Use an animated graphic or other visual cue to
    distract the user.
  • Regularly call Control.Update() to keep the UI
    painting itself.
  • Sure, its cheesy but it often works and its
    easy to implement!

7
External Processes
  • Kick off command-line executables.
  • The ultimate in process isolation!
  • If the background task crashes, your main program
    is not directly affected.
  • Use Process.Start() to begin execution.
  • Process.WaitForExit() can be used to block until
    a spawned process returns.

8
Message Queuing
  • Based on MSMQ.
  • Anything can be placed in a queue for later
    processing
  • Strings
  • XML Messages (SOAP or hand-rolled)
  • Any serializable object
  • Can use Xml (the default), Binary, or ActiveX
    (VB6 interoperability) formatters.

9
Message Queuing (cont.)
  • Can attach to a queue on the local machine, or on
    a remote machine.
  • Beware of security rights issues when creating
    and connecting to queues.
  • Use MessageQueue.Send() to send (push) a message.
  • Use MessageQueue.Receive() to read (pop) a
    message.
  • There is also a BeginReceive() Async method to
    read without blocking.

10
Multithreading
  • There are three categories of threads in .NET
  • CLR Threads
  • Maintained by the CLR
  • No control over these
  • One we all deal with is the main UI Pump
  • ThreadPool threads
  • Quick way to use multithreading
  • Explicit threads
  • Offer the most power, flexibility, and bugs.

11
About the ThreadPool
  • There is only one thread pool per Process.
  • Many framework objects use the thread pool
    internally.
  • There are a fixed number of threads in the pool
    (this limit is not configurable).
  • Once exhausted, queued work items will have to
    wait until a pool thread is released.
  • Offers easy access, but little control.

12
Using the ThreadPool
  • Call ThreadPool.QueueUserWorkItem() to submit a
    task for background execution.
  • ThreadPool.RegisterWaitForSingleObject asks the
    thread pool to watch for an event to become
    signaled, and then call back on another pooled
    thread.
  • Async delegates and Threading.Timer use the
    thread pool internally.

13
Async Delegates
  • Compiler magic automatically adds a BeginInvoke
    and EndInvoke signature to delegates that allow
    them to be called using the thread pool.
  • Use BeginInvoke() to submit the delegate to the
    pool.
  • (important) Every call to BeginInvoke needs to be
    paired with EndInvoke to clean up resources.

14
Async Delegates (cont.)
  • BeginInvoke() returns an IAsyncResult reference
    that is used later to call EndInvoke().
  • An optional callback method can be passed to
    BeginInvoke that will be executed by the
    ThreadPool once the async call has completed.

15
Async Delegates (example)
  • Issuing multiple database queries concurrently

16
Using Explicit Threads
  • Explicit threads require a specific type of
    delegate the ThreadStart delegate.
  • ThreadStart defines a simple method with no
    parameters and no return value.
  • Instantiate a new Thread object using a
    ThreadStart delegate.
  • Once created, a thread must be Started, and once
    the delegate has ended, it cannot be re-used. It
    must be destroyed.

17
So how do we get data in or out?
  • The Thread class itself is sealed ?
  • Must create your own class to manage the threads
    lifetime, and add your own specific data as
    properties.
  • Assign the input properties before Starting.
  • Use an endless loop with ResetEvents to control
    iteration and loop exit point.
  • Signal an event when a task iteration is complete
    to notify the calling code.

18
DEMO 1
  • A Custom Thread manager class to demonstrate
  • Using events to control thread iteration and
    completion
  • Using ThreadPool.RegisterWaitHandle()
  • Using Thread/ThreadStart
  • Performing UI Pump Thread Marshalling using
    Control.Invoke()

19
Explicit Threads (cont.)
  • It is recommended that you not use Thread.Suspend
    or Thread.Resume for flow control. In fact, these
    methods are marked as Obsolete() in Framework
    2.0.
  • Use ManualResetEvent, AutoResetEvent, and Monitor
    for flow control.
  • It is recommended also that you not use
    Thread.Abort(). This is a nasty way to interrupt
    a thread. Use an event instead.

20
Explicit Threads (cont.)
  • Thread.IsBackground is used to mark a thread as
    being non-critical.
  • Background threads will not prevent the CLR from
    ending a process if they are still running during
    shutdown.
  • Thread.Name can be used to give a descriptive
    name that can be seen in the debuggers thread
    list.

21
Real-World Uses
  • Windows Forms Applications To perform intensive
    processing in the background while continuing to
    interact with the user.
  • ASP.NET To perform multiple operations in
    parallel instead of one at a time (multiple
    database queries, etc).
  • The Async Design pattern can be incorporated into
    Data Access Layer code (if you use code
    generation techniques).

22
Making It Work
  • Synchronizing data access
  • Use lock() / SyncLock to wrap complex data
    manipulations into atomic units.
  • Lock() is a compiler macro the IL actually
    contains calls to the Monitor class.
  • You can use the MethodImpl() attribute to cause
    the CLR to effectively wrap a method call in
    lock(this).

23
Cautions for using lock()
  • Do not use Value Types for the locking object.
    They get boxed, causing the locks to be placed on
    different objects each call.
  • Do not use lock() on any publicly accessible
    object. This includes
  • lock(typeof(MyType))
  • lock(some string)
  • lock(MyForm.APublicProperty)
  • lock(this)
  • Public objects can be interfered with!

24
Cautions for using lock() (cont.)
  • You can use more than one locking object in a
    class to improve concurrency.
  • A locking object should be used for each logical
    data element you intend to protect.
  • Locking object example

25
The Interlocked Class
  • Allows quick, simple protection of basic data
    manipulations.
  • Effectively wraps a simple common multi-step
    operation in a lock() statement.
  • Interlocked.Increment()
  • Interlocked.Decrement()
  • Interlocked.CompareExchange()
  • Interlocked.Exchange()

26
The ReaderWriterLock Class
  • Allows optimized locking for data that is read
    often but written rarely.
  • Similar to Monitor, but allows any number of
    readers concurrently.
  • Only allows a single Writer, which requires
    exclusive access.
  • As with all locking mechanisms, acquire late and
    release early!

27
Event Classes
  • ManualResetEvent / AutoResetEvent
  • Have two states signaled and unsignaled
  • Are used to communicate between threads within a
    process.
  • AutoResetEvent is toggled to the Unsignaled state
    automatically the ManualResetEvent remains
    signaled until Reset() is called.
  • Mutex is very similar to ResetEvents, but can be
    associated with a Name, and can be referenced in
    other processes.

28
Interacting With the UI Pump
  • The main UI Pump Thread is the only thread
    allowed to touch GDI objects.
  • Always use Control.Invoke() to pass execution to
    the UI thread from a secondary thread.
  • Can use Control.InvokeRequired to determine if
    you are already in the UI Thread.
  • Beware Invoke runs inside the message pump
    thereby blocking it so its SLOW!

29
Timers
  • Timers are used to fire a repeating event on a
    regular interval.
  • There are three timer classes one in
    System.Windows.Forms another in System.Threading,
    and the third in System.Timers.

30
System.Windows.Forms.Timer
  • Uses the main UI Pump.
  • Inserts a message into the UI stream to process
    the recurring event.
  • Timer event delegate is always called on the main
    UI Thread.
  • Is not very accurate, since it depends on the
    main UI thread to initiate events, which might be
    busy with other tasks.
  • Iterations can be skipped if UI is busy.

31
System.Threading.Timer
  • Uses a background thread to spawn worker threads
    in the thread pool for each iteration.
  • Is more accurate but must use Control.Invoke() if
    it eventually interacts with the UI.
  • Has a more cumbersome interface than the other
    timers, but more flexibility.

32
System.Timers.Timer
  • Uses a background thread to spawn worker threads
    in the thread pool for each iteration.
  • If the SynchronizingObject property is assigned
    to a UI Control, callbacks will automatically be
    marshaled to the UI Thread.
  • If the UI Thread is busy, triggered events will
    queue up until processed.

33
Conversing Between Threads
  • Dont use Suspend/Resume to control threads.
  • Instead, use Events and Mutexes to coordinate
    them.
  • When using an explicit thread, use a while loop
    that watched for an Event to exit. This is more
    efficient that creating a new thread for every
    iteration.

34
Race Conditions
  • Occurs when two threads contend for the same data
    in an unsynchronized way.
  • Causes logical data corruption or inconsistency
    of data.
  • Solution Use Interlocked to protect simple
    operations, and Monitor (or ReaderWriterLock) to
    protect more complex interactions.

35
Deadlocks
  • Occurs when two threads are waiting on a resource
    exclusively held by the other.
  • Solution Ensure that resources are accessed in
    the same order always.
  • Be careful when executing threads on the
    threadpool try to not create even more
    threadpool threads (BeginXxx on a delegate for
    example) and then block on them this will
    exhaust the pool, effectively deadlocking it.

36
New For Framework 2.0
  • BackgroundWorker Class
  • Uses an event-based mechanism to process
    background tasks.
  • Handles main UI Thread synchronization
    automagically.
  • Supports Progress Reporting / Completion
    Notification Events.
  • Supports Cancellation of Worker Task

37
The BackgroundWorker Class
  • Uses a pooled worker thread to process the
    background task, and then executes a completion
    callback on the main UI thread.
  • This async patterns is also baked in to the
    ADO.NET 2.0 and Web Service Proxy classes.
  • This is all possible in todays framework,
    however you need to build your own worker classes
    or set up the delegates to marshal calls back
    into the UI Thread.

38
Resources
  • MSDN Library http//msdn.microsoft.com/library/
  • Newsgroups
  • http//groups.google.com/ or http//www.msdn.micr
    osoft.com/newsgroups/
Write a Comment
User Comments (0)
About PowerShow.com