Upload
intertech-training
View
276
Download
1
Tags:
Embed Size (px)
DESCRIPTION
This presentation will introduce developers to past and current multithreaded programming techniques using C#, .NET 4.5, and Visual Studio 2013. It first introduces the purpose, advantages, and risks of implementing parallel programming in your .NET solutions. Next, it introduces the .NET 4.0 Task Parallel Library (TPL) as a simple way to run several tasks simultaneously. The primitive synchronization types are then covered, explaining what they are and how to use them effectively. Thread-safe data structures and collections are also covered for controlling access to data in a safe manner. As well, techniques for maintaining an interactive user interface during background processing is discussed. The new async/await keywords introduced with .NET 4.5 for non-blocking event handling are also covered. The presentation wraps up with an introduction to multithreaded debugging in Visual Studio 2013. 1. Introduction to Multithreaded Programming 2. Introducing the Parallel Library (TPL) 3. Primitive Types 4. Thread-Safe Collections 5. User Interface (UI) Threading Techniques 6. async and await 7. Debugging Async Code in Visual Studio 2013
Citation preview
An Intertech Course
Asynchronous Programming Techniques with .NET 4.5
Intertech’s Oxygen Blast Davin Mickelson, [email protected]
Oxygen Blast Series
Slide 2 of 39@IntertechInc #oxygenblast
Intertech
Training Training through hands-on, real
world business examples. Our site, your site, or live
online – globally. Agile/Scrum, Citrix, VMware,
Oracle, IBM, Microsoft, Java/Open Source, and web and mobile technologies.
Consulting Design and develop software
that powers businesses and governments of all sizes.
On-site consulting, outsourcing, and mentoring.
Agile, .NET, Java, SQL Server, mobile development including iPhone and Android platforms and more….
Instructors Who Consult, Consultants Who Teach
Our Company Over 35 awards for growth,
innovation and workplace best practices.
99.7% satisfaction score from our consulting and training customers.
Yearly “Best Places to Work” winner in Minnesota.
Oxygen Blast Series
Slide 3 of 39@IntertechInc #oxygenblast
About Me… Developed applications since 1995 with:
Pascal, Assembly, TSO, C, C++, Perl, ColdFusion, ASP ASP.NET, C#, VB, F# SSAS, DTS, SSIS, SSRS
Intertech Consultant/Instructor/Author since 2005 Intertech Courses:
Complete ASP.NET 4.5 (5 days) Programming in HTML5 with JavaScript and CSS3 (5 days) Developing ASP.NET MVC Web Applications (5 days) Programming in C# (5 days) Developing Applications Using Entity Framework 4.1 (2 days) SQL Server Business Intelligence Courses
Intertech blog: http://www.intertech.com/blog
Oxygen Blast Series
Slide 4 of 39@IntertechInc #oxygenblast
Agenda1. Introduction to Multithreaded Programming2. Primitive Types3. Thread-Safe Collections4. Introducing the Parallel Library (TPL)5. User Interface (UI) Threading Techniques6. async and await7. Debugging Async Code in Visual Studio 2013
This presentation will roughly be 60 to 90 minutes
Oxygen Blast Series
Slide 5 of 39@IntertechInc #oxygenblast
How it works Why bother? Simple example with the Thread class Parallel Programming Design Patterns
1. Introduction to Multithreaded Programming
Oxygen Blast Series
Slide 6 of 39@IntertechInc #oxygenblast
Asynchronous Programming is performing two more processing tasks simultaneously Since the late 60’s
These threads of execution share the process's resources, but are able to execute independently
Synchronous processing is the opposite Complete task A, then complete task B, and so on
Also called Parallel programming, Concurrent programming, and Multithreaded programming Not exactly the same though…
Not unique to .NET Used in C, C++, Java, Python, JavaScript, etc.
How It Works
Oxygen Blast Series
Slide 7 of 39@IntertechInc #oxygenblast
It can make an application… Be more efficient (run faster), depending on the types of tasks More responsive Take advantage of multiple processors or processor cores
Why Not? It can make an application… Less efficient, depending on the types tasks Have more complexity Be tougher to test Be tougher to debug Riskier for common multithreaded programming hazards (deadlock,
race conditions, data corruption, etc.)
Why Bother?
Oxygen Blast Series
Slide 8 of 39@IntertechInc #oxygenblast
private static void Main(){ ThreadStart ts = new ThreadStart(Program.DoWork); Thread threadTwo = new Thread(ts); threadTwo.Name = "Buddy"; Console.WriteLine("Buddy thread current state now? {0}", threadTwo.ThreadState); //threadTwo.IsBackground = true; threadTwo.Start(); Thread.Sleep(100); Console.WriteLine("Buddy thread current state now? {0}", threadTwo.ThreadState);}
Simple Example with the Thread Class
Oxygen Blast Series
Slide 9 of 39@IntertechInc #oxygenblast
static void DoWork(){ // Simulating a time-consuming process Thread.Sleep(2000); Thread thisThread = Thread.CurrentThread;
Console.WriteLine("DW: Which thread is this? {0}", thisThread.Name); Console.WriteLine("DW: Buddy thread current state now? {0}", thisThread.ThreadState); Console.WriteLine("DW: Is Background thread? {0}", thisThread.IsBackground); Console.WriteLine("DW: Thread Priority? {0}", thisThread.Priority); Console.WriteLine("DW: Is ThreadPool Thread? {0}", thisThread.IsThreadPoolThread);}
Simple Example with the Thread Class
Oxygen Blast Series
Slide 10 of 39@IntertechInc #oxygenblast
SimpleThreadExample Creating a ThreadStart type is optional The thread dies when the method completes Primary thread won’t wait for background threads Calling Sleep() on second thread changes it’s state to
WaitSleepJoin Best not to mess with thread priority – perhaps lower the
priority of a runaway thread
Simple Example with the Thread Class (cont.)
Oxygen Blast Series
Slide 11 of 39@IntertechInc #oxygenblast
Asynchronous Programming Model (APM) (legacy) Uses BeginOpName(), EndOpName(), and IAsyncResult types Supports Polling, Waiting, and Callback methods
Event-based Asynchronous Pattern (EAP) (legacy) Within a class, have a MethodNameAsync() method with a corresponding
MethodNameCompleted event Run xxxAsync() methods in background, keeping UI interactive Uses SendOrPostCallback delegate type
Task-based Asynchronous Pattern (TAP) (for new development) Based on System.Threading.Tasks.Task Uses a single method to launch. More later!
More design pattern information:http://msdn.microsoft.com/en-us/library/vstudio/hh156548(v=vs.110).aspx
Parallel Programming Design Patterns
Oxygen Blast Series
Slide 12 of 39@IntertechInc #oxygenblast
Barrier Allows tasks to take turns processing an algorithm No thread gets left behind. Wait for other threads to take their turn
before continuing Interlocked
Allows simple thread safe ways to increment, decrement, compare, and exchange variables.
LazyInitializer Guarantees objects have been initialized, so long as they are needed
ManualResetEvent Notifies one or more waiting threads that an event has occurred
2. Primitive Types
Oxygen Blast Series
Slide 13 of 39@IntertechInc #oxygenblast
Monitor Allows the thread to create a lock over a specified object. Used to guard a critical section of code, where only one thread should ever
enter at a time The C# lock() and VB SyncLock() keywords use the Monitor class with the
Enter() and Exit methods Mutex
Mutually Exclusive lock the can be seen by other processes (running applications)
Can be used to control access to a resource shared by processes or synchronize activities between processes
Can also be used to prevent multiple versions of an app running simultaneously
An unnamed mutex is local to process. A named mutex are machine wide
2. Primitive Types (cont.)
Oxygen Blast Series
Slide 14 of 39@IntertechInc #oxygenblast
ReaderWriterLock Allows multiple threads to read an object while only one thread can write
to the object Often times faster than using a Monitor
Semaphore Limits the number of threads to access one or more resources
Thread Represents a thread of execution in an application
ThreadPool A variable-sized group of threads working to complete system tasks Each version of .NET released has modified the number of threads
Timer Calls a specified method at a specified interval
2. Primitive Types (cont.)
Oxygen Blast Series
Slide 15 of 39@IntertechInc #oxygenblast
Slim Primitives ManualResetEventSlim ReaderWriterLockSlim SemaphoreSlim
Introduced with .NET 4.0, these are usually preferred over their parent types, because: Usually safer from threading errors (deadlock, thread starvation, etc.) Easier/Simpler to use Less memory used Higher performance
2. Primitive Types (cont.)
Oxygen Blast Series
Slide 16 of 39@IntertechInc #oxygenblast
Introduced with .NET 4.0, these collections bring the BOBW for managing type-safe collections in a thread-safe manner
The classic .NET 1.0 System.Collections collections (ArrayList, Queue, etc.) did offer some thread safety with the Synchronized property
The .NET 2.0 generic collections are not thread safe at all Some of the Thread-Safe collections (BlockingCollection<T>)
using primitives to control access (SpinLock, SemaphoreSlim) while other collections (ConcurrentQueue<T>, ConcurrentStack<T>) just offer additional methods
3. Thread-Safe Collections
Oxygen Blast Series
Slide 17 of 39@IntertechInc #oxygenblast
Thread-Safe collections in System.Collections.Concurrent
3. Thread-Safe Collections (cont.)
Collection Name Description
BlockingCollection<T> Provides blocking and size-limiting capabilities for thread-safe collections
ConcurrentBag<T> Represents a thread-safe, unordered collection of objects.
ConcurrentDictionary<TKey, TValue>
Represents a thread-safe collection of key/value pairs
ConcurrentQueue<T> Represents a thread-safe first in-first out (FIFO) collection.
ConcurrentStack<T> Represents a thread-safe last in-first out (LIFO) collection.
OrderablePartitioner<TSource> Represents a particular manner of splitting an orderable data source into multiple partitions.
Partitioner Provides common partitioning strategies for arrays, lists, and enumerables.
Partitioner<TSource> Represents a particular manner of splitting a data source into multiple partitions.
Oxygen Blast Series
Slide 18 of 39@IntertechInc #oxygenblast
Example: Stacker project uses ConcurrentStack<T> Note the use of TryPop() Learn more here:
http://msdn.microsoft.com/en-us/library/system.collections.concurrent(v=vs.110).aspx
3. Thread-Safe Collections (cont.)
Oxygen Blast Series
Slide 19 of 39@IntertechInc #oxygenblast
The Task Parallel Library (TPL) was introduced to simplify calling methods to perform work asynchronously Introduced with .NET 4.0, it saves a considerable amount of coding and
uses best practices for performance while preventing exceptions Located in the System.Threading.Tasks namespace
VS 2012 and newer automatically add the “using” statement at the top of the source code files:
4. Introducing the Parallel Library (TPL)
using System.Threading.Tasks;
Oxygen Blast Series
Slide 20 of 39@IntertechInc #oxygenblast
There are some interesting objects in the Tasks namespace! Task Task<TResult> TaskFactory Parallel
The Task class lies at the heart of the TPL Task call methods with a void return type Task<TResult> calls a method that returns a value
Understanding the lambda operator is critical for using the TPL
4. Introducing the Parallel Library (TPL) (cont.)
Oxygen Blast Series
Slide 21 of 39@IntertechInc #oxygenblast
.NET 2.0 introduced the anonymous methods for handling eventsa.MultipleOfFiveReached += delegate(object sender, EventArgs e){ Console.WriteLine("Multiple of five reached!"); Console.WriteLine("Object: {0}, EventArgs: {1}", sender, e);};
Since we know that the MultipleOfFiveReached event is based on the delegate, we can drop the delegate keyword
As well, since we need to pass in parameters, we will use the lambda operator to pass them in
Lambda Breakdown
Oxygen Blast Series
Slide 22 of 39@IntertechInc #oxygenblast
When you see the lambda operator, say to yourself, “…goes into…” for the arguments being passed into the code
a.MultipleOfFiveReached += (object sender, EventArgs e) =>{ Console.WriteLine("Multiple of five reached!"); Console.WriteLine("Object: {0}, EventArgs: {1}", sender, e);};
The Task type uses the lambda operator to call and pass values to anonymous instances of delegates The two most important delegates are Action and Func, located in the
mscorlib and System.Core assemblies These delegates are also the same ones use by LINQ Extension
methods!
Lambda Breakdown
Oxygen Blast Series
Slide 23 of 39@IntertechInc #oxygenblast
A Task represents an asynchronous unit of work It represents a chunk of code that is going to run separately while the
main chunk of code continues to execute A single Task appears to operate very much like a Thread:private static void Main(){ Task t = new Task(DisplayTime); t.Start(); // PROBLEM! Doesn’t wait to allow Task to finish!}
private static void DisplayTime(){ Console.WriteLine(DateTime.Now.ToLongTimeString());}
Using Task
Oxygen Blast Series
Slide 24 of 39@IntertechInc #oxygenblast
The Wait() method will pause execution of the main thread until it has completed.
private static void Main(){ Task t = new Task(DisplayTime); t.Start(); t.Wait(); // PROBLEM SOLVED! Waiting until finished.}
private static void DisplayTime(){ Console.WriteLine(DateTime.Now.ToLongTimeString());}
Using Task
Oxygen Blast Series
Slide 25 of 39@IntertechInc #oxygenblast
The Action delegate can be used to call the methodprivate static void Main(){ Task t = new Task(new Action(DisplayTime)); t.Start(); t.Wait();}private static void DisplayTime(){ Console.WriteLine(DateTime.Now.ToLongTimeString());}
Using Task
Oxygen Blast Series
Slide 26 of 39@IntertechInc #oxygenblast
Using the Task.Factory.StartNew() method, we can shorten the code even more:
private static void Main(){ Task t = Task.Factory.StartNew(DisplayTime); t.Wait();}private static void DisplayTime(){ Console.WriteLine(DateTime.Now.ToLongTimeString());}
Using Task
Oxygen Blast Series
Slide 27 of 39@IntertechInc #oxygenblast
The Func delegate can be used to call the method and return a value This code is becoming really long. Time for lambda! =>
private static void Main(){ Task<string> t = new Task<string>(new Func<string>(DisplayTime)); t.Start(); t.Wait(); Console.WriteLine(t.Result);}
private static string DisplayTime(){ return DateTime.Now.ToLongTimeString();}
Using Task
Oxygen Blast Series
Slide 28 of 39@IntertechInc #oxygenblast
Using the Task.Run() method and the lambda operator, we can shorten the code even further: No arguments are passed into DisplayTime()
private static void Main(){ //Task<string> t = new Task<string>(new Func<string>(DisplayTime)); Task<string> t = Task.Run<string>(() => DisplayTime()); //t.Start(); // No need to wait either! Console.WriteLine(t.Result);}
private static string DisplayTime(){ return DateTime.Now.ToLongTimeString();}
Using Task
Oxygen Blast Series
Slide 29 of 39@IntertechInc #oxygenblast
The Parallel class can be used to execute several tasks simultaneously With Parallel, you can use the Invoke(), For(), and Foreach() methods
Invoke() Creates tasks for you, calling the methods you specify For() loops a predetermined number of times ForEach() is perfect for cycling through an array or collection
Using Parallel
Oxygen Blast Series
Slide 30 of 39@IntertechInc #oxygenblast
private static void Main(){ //int iThreadCount = 3; // CHANGE THIS FOR FUN! int iOrderCount = 100; // CHANGE THIS FOR FUN! PlaceOrdersInStack(iOrderCount); //Thread[] myWorkers = new Thread[iThreadCount]; //for (int i = 0; i < iThreadCount; i++) //{ // myWorkers[i] = new Thread(ProcessOrdersInStack); // myWorkers[i].Start(); //} Parallel.Invoke(() => ProcessOrdersInStack(), () => ProcessOrdersInStack(), () => ProcessOrdersInStack()); Console.WriteLine("Main Thread Done!");}
Using Parallel.Invoke( ) with three tasks
Oxygen Blast Series
Slide 31 of 39@IntertechInc #oxygenblast
private static void Main(){ int iOrderCount = 100; // CHANGE THIS FOR FUN! PlaceOrdersInStack(iOrderCount);
// Display them individually Parallel.For(0, OrderStack.Count, (index) => DisplaySingleOrder(index));}
private static void DisplaySingleOrder(int iOrder){ Console.WriteLine("Order details: {0}", OrderStack.ElementAt(iOrder));}
Using Parallel.For( ) to display
Oxygen Blast Series
Slide 32 of 39@IntertechInc #oxygenblast
As a best practice, only the main thread should ever update the user interface Child threads/tasks should not be in control of the user interface or
block the user from interacting with it Whether it be a Windows Forms application, WPF application,
or Windows Universal application, you should consider using Tasks or the BackgroundWorker type
You can update progress to user or cancel the work Learn more here, including a code example:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx
5. User Interface (UI) Threading Techniques
Oxygen Blast Series
Slide 33 of 39@IntertechInc #oxygenblast
The async and await keywords were introduced with .NET 4.5 They make it even easier to perform asynchronous operations when a
User Interface (UI) is involved They allow a method (such as an event handler) that is running
on the primary thread to immediately return to allow the UI to remain interactive This same thread can also run another chunk of code (such as another
method) to process data. When the method has complete, this same thread can then update the
UI with the information
6. async and await
Oxygen Blast Series
Slide 34 of 39@IntertechInc #oxygenblast
private async void btnGetDate_Click(object sender, EventArgs e){ lblDate.Text = await GetTime();}
private async Task<string> GetTime(){ string sResult = await Task.Run<string>(() => { Thread.Sleep(5000); return DateTime.Now.ToLongDateString(); }); return sResult;}
Using async and await in WinForms
Oxygen Blast Series
Slide 35 of 39@IntertechInc #oxygenblast
Use the new Debug windows in Visual Studio There are windows for threads, Tasks, and Thread Watches Note that these menu option are only available during a debug
session C++ developers also have a new thread debugger (C++ AMP)
with Visual Studio 2012 It can debug GPU threads for graphics!
7. Debugging Async Code in Visual Studio 2013
Oxygen Blast Series
Slide 36 of 39@IntertechInc #oxygenblast
7. Debugging Async Code in Visual Studio 2013
Oxygen Blast Series
Slide 37 of 39@IntertechInc #oxygenblast
Book: Pro Asynchronous Programming with .NET Apress, ISBN: 978-1-4302-5920-6
Book: Pro .NET Performance Apress, ISBN: 978-1-4302-4458-5
Book: Concurrency in C# Cookbook O’Reilly, ISBN: 978-1-44936-756-5
Book: .NET 4.5 Parallel Extensions Cookbook Packt, ISBN: 978-1-84969-002-5
Blog: Microsoft Parallel Programming with .NET http://blogs.msdn.com/b/pfxteam/
Resources
Oxygen Blast Series
Slide 38 of 39@IntertechInc #oxygenblast
Next Oxygen Blasts The Future of iPhone & iPad Programming with Swift
October 13th, 1:00 CDT p.m.
C# Training Programming in C#, 20483B Advanced C# Programming with VS 2012
C# Consulting .NET consulting using C# for development
Upcoming Webinars and Training
Oxygen Blast Series
Slide 39 of 39@IntertechInc #oxygenblast
Questions or Feedback?Patrick Schaber – [email protected]
Davin Mickelson – [email protected]
Thank You!