Free mag vol1 | Page 752

C H A P T E R 19 Multithreaded, Parallel, and Async Programming Nobody enjoys working with an application that is slow and sluggish during its execution. Moreover, nobody enjoys starting a task in an application (perhaps initiated by the clicking of a toolbar item) that prevents other parts of the program from being as responsive as possible. Before the release of .NET, building applications that had the ability to perform multiple tasks required authoring very complex C++ code that made use of the Windows threading APIs. Thankfully, the .NET platform provides a number of ways for you to build software that can perform complex operations on unique paths of execution, with far fewer pain points. This chapter begins by defining the overall nature of a “multithreaded application.” Next, we will revisit the .NET delegate type to investigate its intrinsic support for asynchronous method invocations. As you’ll see, this technique allows you to invoke a method on a secondary thread of execution without needing to manually create or configure the thread itself. Next, you’ll be introduced to the original threading namespace which has shipped since .NET 1.0, specifically System.Threading. Here you’ll examine numerous types (Thread, ThreadStart, etc.) that allow you to explicitly create additional threads of execution and synchronize your shared resources, which helps ensure that multiple threads can share data in a nonvolatile manner. The remaining parts of this chapter will examine three more recent techniques .NET developers can make use of to build multithreaded software, specifically the Task Parallel Library (TPL), Parallel LINQ (PLINQ), and the new intrinsic asynchronous keywords of C# (async and await). As you will see, these features can dramatically simplify how you can build responsive multithreaded software applications. The Process/AppDomain/Context/Thread Relationship In Chapter 17, a thread was defined as a path of execution within an executable application. While many .NET applications can live happy and productive single-threaded lives, an assembly’s primary thread (spawned by the CLR when Main() executes) may create secondary threads of execution at any time to perform additional units of work. By creating additional threads, you can build more responsive (but not necessarily faster executing on single-core machines) applications. The System.Threading namespace was released with .NET 1.0, and offers one approach to build multithreaded applications. The Thread class is perhaps the core type, as it represents a given thread. If you want to programmatically obtain a reference to the thread currently executing a given member, simply call the static Thread.CurrentThread property, like so: static void ExtractExecutingThread() { // Get the thread currently // executing this method. 697