0% found this document useful (0 votes)
150 views81 pages

Multithreading With C Cookbook 2nd Edition Eugene Agafonov PDF Download

The document is a promotional description of the 'Multithreading with C# Cookbook, 2nd Edition' by Eugene Agafonov, which provides over 70 recipes for developing multithreaded and asynchronous applications in C#. It includes a comprehensive table of contents detailing various topics such as threading basics, synchronization, task parallel library, and reactive extensions. The book is aimed at C# developers seeking to enhance their skills in multithreading and parallel programming.

Uploaded by

dinzeykhusbo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
150 views81 pages

Multithreading With C Cookbook 2nd Edition Eugene Agafonov PDF Download

The document is a promotional description of the 'Multithreading with C# Cookbook, 2nd Edition' by Eugene Agafonov, which provides over 70 recipes for developing multithreaded and asynchronous applications in C#. It includes a comprehensive table of contents detailing various topics such as threading basics, synchronization, task parallel library, and reactive extensions. The book is aimed at C# developers seeking to enhance their skills in multithreading and parallel programming.

Uploaded by

dinzeykhusbo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 81

Multithreading with C Cookbook 2nd Edition

Eugene Agafonov pdf download

https://ebookgate.com/product/multithreading-with-c-cookbook-2nd-
edition-eugene-agafonov/

Get Instant Ebook Downloads – Browse at https://ebookgate.com


Instant digital products (PDF, ePub, MOBI) available
Download now and explore formats that suit you...

Case files Family medicine 2nd Edition Eugene C Toy

https://ebookgate.com/product/case-files-family-medicine-2nd-edition-
eugene-c-toy/

ebookgate.com

C Concurrency in Action Practical Multithreading MEAP 1st


Edition Anthony Williams

https://ebookgate.com/product/c-concurrency-in-action-practical-
multithreading-meap-1st-edition-anthony-williams/

ebookgate.com

Machine Learning with R Cookbook 2nd Edition Ashishsingh


Bhatia

https://ebookgate.com/product/machine-learning-with-r-cookbook-2nd-
edition-ashishsingh-bhatia/

ebookgate.com

Case Files Obstetrics and Gynecology Lange Case Files 2nd


Edition Eugene C. Toy

https://ebookgate.com/product/case-files-obstetrics-and-gynecology-
lange-case-files-2nd-edition-eugene-c-toy/

ebookgate.com
Case Files Internal Medicine 4th Edition Eugene C. Toy

https://ebookgate.com/product/case-files-internal-medicine-4th-
edition-eugene-c-toy/

ebookgate.com

Web Development with Django Cookbook Bendoraitis

https://ebookgate.com/product/web-development-with-django-cookbook-
bendoraitis/

ebookgate.com

Case Files Neuroscience Case Files 1st Edition Eugene C.


Toy

https://ebookgate.com/product/case-files-neuroscience-case-files-1st-
edition-eugene-c-toy/

ebookgate.com

C Cookbook 2e éd. Edition Stephens

https://ebookgate.com/product/c-cookbook-2e-ed-edition-stephens/

ebookgate.com

Programming with ANSI C 2nd ed Edition Trivedi

https://ebookgate.com/product/programming-with-ansi-c-2nd-ed-edition-
trivedi/

ebookgate.com
Multithreading with
C# Cookbook
Second Edition

Over 70 recipes to get you writing powerful


and efficient multithreaded, asynchronous,
and parallel programs in C# 6.0

Eugene Agafonov

BIRMINGHAM - MUMBAI
Multithreading with C# Cookbook
Second Edition

Copyright © 2016 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system,
or transmitted in any form or by any means, without the prior written permission of the
publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the
information presented. However, the information contained in this book is sold without
warranty, either express or implied. Neither the author, nor Packt Publishing, and its
dealers and distributors will be held liable for any damages caused or alleged to be
caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the
companies and products mentioned in this book by the appropriate use of capitals.
However, Packt Publishing cannot guarantee the accuracy of this information.

First published: November 2013


Second Edition: April 2016

Production reference: 1150416

Published by Packt Publishing Ltd.


Livery Place
35 Livery Street
Birmingham B3 2PB, UK.

ISBN 978-1-78588-125-1

www.packtpub.com
Credits

Author Copy Editor


Eugene Agafonov Neha Vyas

Reviewers Project Coordinator


Chad McCallum Francina Pinto
Philip Pierce
Proofreader
Commissioning Editor Safis Editing
Edward Gordon
Indexer
Acquisition Editor Rekha Nair
Kirk D'Costa
Production Coordinator
Content Development Editor Manu Joseph
Nikhil Borkar
Cover Work
Technical Editor Manu Joseph
Vivek Pala
About the Author

Eugene Agafonov leads the development department at ABBYY and lives in Moscow.
He has over 15 years of professional experience in software development, and he started
working with C# when it was in beta version. He is a Microsoft MVP in ASP.NET since 2006,
and he often speaks at local software development conferences, such as DevCon Russia,
about cutting-edge technologies in modern web and server-side application development. His
main professional interests are cloud-based software architecture, scalability, and reliability.
Eugene is a huge fan of football and plays the guitar with a local rock band. You can reach him
at his personal blog, eugeneagafonov.com, or find him on Twitter at @eugene_agafonov.

ABBYY is a global leader in the development of document recognition, content capture, and
language-based technologies and solutions that are integrated across the entire information
life cycle.

He is the author of Multhreading in C# 5.0 Cookbook and Mastering C# Concurrency


by Packt Publishing.

I'd like to dedicate this book to my dearly beloved wife, Helen, and son,
Nikita.
About the Reviewers

Chad McCallum is a Saskatchewan computer geek with a passion for software


development. He has over 10 years of .NET experience (and 2 years of PHP, but we won't
talk about that). After graduating from SIAST Kelsey Campus, he picked up freelance PHP
contracting work until he could pester iQmetrix to give him a job, which he's hung onto for
the last 10 years. He's come back to his roots in Regina and started HackREGINA, a local
hackathon organization aimed at strengthening the developer community while coding and
drinking beer. His current focus is mastering the art of multitenant e-commerce with .NET.
Between his obsession with board gaming and random app ideas, he tries to learn a new
technology every week. You can see the results at www.rtigger.com.

Philip Pierce is a software developer with 20 years of experience in mobile, web, desktop,
and server development, database design and management, and game development. His
background includes creating A.I. for games and business software, converting AAA games
between various platforms, developing multithreaded applications, and creating patented
client/server communication technologies.

Philip has won several hackathons, including Best Mobile App at the AT&T Developer
Summit 2013, and a runner up for Best Windows 8 App at PayPal's Battlethon Miami.
His most recent project was converting Rail Rush and Temple Run 2 from the Android
platform to Arcade platforms.

Philip's portfolios can be found at the following websites:

f http://www.rocketgamesmobile.com
f http://www.philippiercedeveloper.com
www.PacktPub.com

eBooks, discount offers, and more


Did you know that Packt offers eBook versions of every book published, with PDF and ePub
files available? You can upgrade to the eBook version at www.PacktPub.com and as a print
book customer, you are entitled to a discount on the eBook copy. Get in touch with us at
[email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up
for a range of free newsletters and receive exclusive discounts and offers on Packt books
and eBooks.
TM

https://www2.packtpub.com/books/subscription/packtlib

Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book
library. Here, you can search, access, and read Packt's entire library of books.

Why Subscribe?
f Fully searchable across every book published by Packt
f Copy and paste, print, and bookmark content
f On demand and accessible via a web browser
Table of Contents
Preface v
Chapter 1: Threading Basics 1
Introduction 2
Creating a thread in C# 2
Pausing a thread 6
Making a thread wait 7
Aborting a thread 8
Determining a thread state 10
Thread priority 12
Foreground and background threads 14
Passing parameters to a thread 16
Locking with a C# lock keyword 19
Locking with a Monitor construct 22
Handling exceptions 24
Chapter 2: Thread Synchronization 27
Introduction 27
Performing basic atomic operations 28
Using the Mutex construct 31
Using the SemaphoreSlim construct 32
Using the AutoResetEvent construct 34
Using the ManualResetEventSlim construct 36
Using the CountDownEvent construct 38
Using the Barrier construct 39
Using the ReaderWriterLockSlim construct 41
Using the SpinWait construct 44

i
Table of Contents

Chapter 3: Using a Thread Pool 47


Introduction 47
Invoking a delegate on a thread pool 49
Posting an asynchronous operation on a thread pool 52
A thread pool and the degree of parallelism 54
Implementing a cancellation option 56
Using a wait handle and timeout with a thread pool 59
Using a timer 61
Using the BackgroundWorker component 63
Chapter 4: Using the Task Parallel Library 67
Introduction 67
Creating a task 69
Performing basic operations with a task 70
Combining tasks 72
Converting the APM pattern to tasks 75
Converting the EAP pattern to tasks 79
Implementing a cancelation option 81
Handling exceptions in tasks 83
Running tasks in parallel 85
Tweaking the execution of tasks with TaskScheduler 87
Chapter 5: Using C# 6.0 93
Introduction 93
Using the await operator to get asynchronous task results 96
Using the await operator in a lambda expression 98
Using the await operator with consequent asynchronous tasks 100
Using the await operator for the execution of parallel asynchronous tasks 102
Handling exceptions in asynchronous operations 104
Avoiding the use of the captured synchronization context 107
Working around the async void method 111
Designing a custom awaitable type 114
Using the dynamic type with await 118
Chapter 6: Using Concurrent Collections 123
Introduction 123
Using ConcurrentDictionary 125
Implementing asynchronous processing using ConcurrentQueue 127
Changing asynchronous processing order with ConcurrentStack 130
Creating a scalable crawler with ConcurrentBag 132
Generalizing asynchronous processing with BlockingCollection 136

ii
Table of Contents

Chapter 7: Using PLINQ 141


Introduction 141
Using the Parallel class 143
Parallelizing a LINQ query 145
Tweaking the parameters of a PLINQ query 148
Handling exceptions in a PLINQ query 151
Managing data partitioning in a PLINQ query 153
Creating a custom aggregator for a PLINQ query 157
Chapter 8: Reactive Extensions 161
Introduction 161
Converting a collection to an asynchronous Observable 162
Writing custom Observable 165
Using the Subjects type 168
Creating an Observable object 172
Using LINQ queries against an observable collection 174
Creating asynchronous operations with Rx 177
Chapter 9: Using Asynchronous I/O 181
Introduction 181
Working with files asynchronously 183
Writing an asynchronous HTTP server and client 187
Working with a database asynchronously 190
Calling a WCF service asynchronously 194
Chapter 10: Parallel Programming Patterns 199
Introduction 199
Implementing Lazy-evaluated shared states 200
Implementing Parallel Pipeline with BlockingCollection 205
Implementing Parallel Pipeline with TPL DataFlow 210
Implementing Map/Reduce with PLINQ 215
Chapter 11: There's More 221
Introduction 221
Using a timer in a Universal Windows Platform application 223
Using WinRT from usual applications 227
Using BackgroundTask in Universal Windows Platform applications 230
Running a .NET Core application on OS X 237
Running a .NET Core application on Ubuntu Linux 240
Index 243

iii
Preface
Not so long ago, a typical personal computer CPU had only one computing core, and the
power consumption was enough to cook fried eggs on it. In 2005, Intel introduced its first
multiple-core CPU, and since then, computers started developing in a different direction.
Low-power consumption and a number of computing cores became more important than
a row computing core performance. This lead to programming paradigm changes as well.
Now, we need to learn how to use all CPU cores effectively to achieve the best performance,
and at the same time, we need to save battery power by running only the programs that we
need at a particular time. Besides that, we need to program server applications in a way to
use multiple CPU cores or even multiple computers as efficiently as possible to support as
many users as we can.

To be able to create such applications, you have to learn to use multiple CPU cores in your
programs effectively. If you use the Microsoft .NET development platform and C#, this book
will be a perfect starting point for you to program fast and responsive applications.

The purpose of this book is to provide you with a step-by-step guide for multithreading and
parallel programming in C#. We will start with the basic concepts, going through more and
more advanced topics based on the information from previous chapters, and we will end with
real-world parallel programming patterns, Universal Windows applications, and cross-platform
applications samples.

What this book covers


Chapter 1, Threading Basics, introduces the basic operations with threads in C#. It explains
what a thread is, the pros and cons of using threads, and other important thread aspects.

Chapter 2, Thread Synchronization, describes thread interaction details. You will learn why we
need to coordinate threads together and the different ways of organizing thread coordination.

Chapter 3, Using a Thread Pool, explains the thread pool concept. It shows how to use a
thread pool, how to work with asynchronous operations, and the good and bad practices
of using a thread pool.

v
Preface

Chapter 4, Using the Task Parallel Library, is a deep dive into the Task Parallel Library (TPL)
framework. This chapter outlines every important aspect of TPL, including task combination,
exception management, and operation cancelation.

Chapter 5, Using C# 6.0, explains in detail the recently introduced C# feature—asynchronous


methods. You will find out what the async and await keywords mean, how to use them in
different scenarios, and how await works under the hood.

Chapter 6, Using Concurrent Collections, describes the standard data structures for parallel
algorithms included in .NET Framework. It goes through sample programming scenarios for
each data structure.

Chapter 7, Using PLINQ, is a deep dive into the Parallel LINQ infrastructure. The chapter
describes task and data parallelism, parallelizing a LINQ query, tweaking parallelism options,
partitioning a query, and aggregating the parallel query result.

Chapter 8, Reactive Extensions, explains how and when to use the Reactive Extensions
framework. You will learn how to compose events and how to perform a LINQ query against
an event sequence.

Chapter 9, Using Asynchronous I/O, covers in detail the asynchronous I/O process, including
files, networks, and database scenarios.

Chapter 10, Parallel Programming Patterns, outlines the solutions to common parallel
programming problems.

Chapter 11, There's More, covers the aspects of programming asynchronous applications for
Windows 10, OS X, and Linux. You will learn how to work with Windows 10 asynchronous APIs
and how to perform the background work in Universal Windows applications. Also, you will get
familiar with cross-platform .NET development tools and components.

What you need for this book


For most of the recipes, you will need Microsoft Visual Studio Community 2015. The recipes
in Chapter 11, There's more, for OS X and Linux will optionally require the Visual Studio Code
editor. However, you can use any specific editor you are familiar with.

Who this book is for


This book is written for existing C# developers with little or no background in multithreading and
asynchronous and parallel programming. The book covers these topics from basic concepts to
complicated programming patterns and algorithms using the C# and .NET ecosystem.

vi
Preface

Conventions
In this book, you will find a number of styles of text that distinguish between different kinds of
information. Here are some examples of these styles, and an explanation of their meaning.

Code words in text are shown as follows: "When the program is run, it creates a thread that
will execute a code in the PrintNumbersWithDelay method."

A block of code is set as follows:


static void LockTooMuch(object lock1, object lock2)
{
lock (lock1)
{
Sleep(1000);
lock (lock2);
}
}

Any command-line input or output is written as follows:


dotnet restore
dotnet run

New terms and important words are shown in bold. Words that you see on the screen, in
menus or dialog boxes for example, appear in the text like this: "Right-click on the References
folder in the project, and select the Manage NuGet Packages… menu option".

Warnings or important notes appear in a box like this.

Tips and tricks appear like this.

vii
Preface

Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this book—
what you liked or may have disliked. Reader feedback is important for us to develop titles that
you really get the most out of.

To send us general feedback, simply send an e-mail to [email protected], and


mention the book title via the subject of your message.

If there is a topic that you have expertise in and you are interested in either writing or
contributing to a book, see our author guide on www.packtpub.com/authors.

Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you to
get the most from your purchase.

Downloading the example code


You can download the example code files for this book from your account at http://
www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.
packtpub.com/support and register to have the files e-mailed directly to you.

You can download the code files by following these steps:

1. Log in or register to our website using your e-mail address and password.
2. Hover the mouse pointer on the SUPPORT tab at the top.
3. Click on Code Downloads & Errata.
4. Enter the name of the book in the Search box.
5. Select the book for which you're looking to download the code files.
6. Choose from the drop-down menu where you purchased this book from.
7. Click on Code Download.

Once the file is downloaded, please make sure that you unzip or extract the folder using the
latest version of:

f WinRAR / 7-Zip for Windows


f Zipeg / iZip / UnRarX for Mac
f 7-Zip / PeaZip for Linux

viii
Preface

Errata
Although we have taken every care to ensure the accuracy of our content, mistakes do
happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—
we would be grateful if you would report this to us. By doing so, you can save other readers
from frustration and help us improve subsequent versions of this book. If you find any errata,
please report them by visiting http://www.packtpub.com/submit-errata, selecting
your book, clicking on the errata submission form link, and entering the details of your
errata. Once your errata are verified, your submission will be accepted and the errata will
be uploaded on our website, or added to any list of existing errata, under the Errata section
of that title. Any existing errata can be viewed by selecting your title from http://www.
packtpub.com/support.

Piracy
Piracy of copyright material on the Internet is an ongoing problem across all media. At Packt,
we take the protection of our copyright and licenses very seriously. If you come across any
illegal copies of our works, in any form, on the Internet, please provide us with the location
address or website name immediately so that we can pursue a remedy.

Please contact us at [email protected] with a link to the suspected pirated material.

We appreciate your help in protecting our authors, and our ability to bring you valuable content.

Questions
You can contact us at [email protected] if you are having a problem with any
aspect of the book, and we will do our best to address it.

ix
Threading Basics
1
In this chapter, we will cover the basic tasks to work with threads in C#. You will learn the
following recipes:

f Creating a thread in C#
f Pausing a thread
f Making a thread wait
f Aborting a thread
f Determining a thread state
f Thread priority
f Foreground and background threads
f Passing parameters to a thread
f Locking with a C# lock keyword
f Locking with a Monitor construct
f Handling exceptions

1
Threading Basics

Introduction
At some point of time in the past, the common computer had only one computing unit and
could not execute several computing tasks simultaneously. However, operating systems could
already work with multiple programs simultaneously, implementing the concept of multitasking.
To prevent the possibility of one program taking control of the CPU forever, causing other
applications and the operating system itself to hang, the operating systems had to split a
physical computing unit across a few virtualized processors in some way and give a certain
amount of computing power to each executing program. Moreover, an operating system must
always have priority access to the CPU and should be able to prioritize CPU access to different
programs. A thread is an implementation of this concept. It could be considered as a virtual
processor that is given to the one specific program and runs it independently.

Remember that a thread consumes a significant amount of operating system


resources. Trying to share one physical processor across many threads will
lead to a situation where an operating system is busy just managing threads
instead of running programs.

Therefore, while it was possible to enhance computer processors, making them execute more
and more commands per second, working with threads was usually an operating system task.
There was no sense in trying to compute some tasks in parallel on a single-core CPU because
it would take more time than running those computations sequentially. However, when
processors started to have more computing cores, older programs could not take advantage
of this because they just used one processor core.

To use a modern processor's computing power effectively, it is very important to be able to


compose a program in a way that it can use more than one computing core, which leads to
organizing it as several threads that communicate and synchronize with each other.

The recipes in this chapter focus on performing some very basic operations with threads
in the C# language. We will cover a thread's life cycle, which includes creating, suspending,
making a thread wait, and aborting a thread, and then, we will go through the basic
synchronization techniques.

Creating a thread in C#
Throughout the following recipes, we will use Visual Studio 2015 as the main tool to write
multithreaded programs in C#. This recipe will show you how to create a new C# program and
use threads in it.

A free Visual Studio Community 2015 IDE can be downloaded from


the Microsoft website and used to run the code samples.

2
Chapter 1

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other
prerequisites. The source code for this recipe can be found in the BookSamples\Chapter1\
Recipe1 directory.

Downloading the example code


You can download the example code files for this book from your account at
http://www.packtpub.com. If you purchased this book elsewhere, you
can visit http://www.packtpub.com/support and register to have the
files e-mailed directly to you.
You can download the code files by following these steps:
f Log in or register to our website using your e-mail address and
password.
f Hover the mouse pointer on the SUPPORT tab at the top.
f Click on Code Downloads & Errata.
f Enter the name of the book in the Search box.
f Select the book for which you're looking to download the code files.
f Choose from the drop-down menu where you purchased this book from.
f Click on Code Download.
Once the file is downloaded, please make sure that you unzip or extract the
folder using the latest version of:
f WinRAR/7-Zip for Windows
f Zipeg/iZip / UnRarX for Mac
f 7-Zip/PeaZip for Linux

How to do it...
To understand how to create a new C# program and use threads in it, perform the
following steps:

1. Start Visual Studio 2015. Create a new C# console application project.

3
Threading Basics

2. Make sure that the project uses .NET Framework 4.6 or higher; however, the code in
this chapter will work with previous versions.

3. In the Program.cs file, add the following using directives:


using System;
using System.Threading;
using static System.Console;

4. Add the following code snippet below the Main method:


static void PrintNumbers()
{
WriteLine("Starting...");
for (int i = 1; i < 10; i++)
{
WriteLine(i);
}
}

4
Chapter 1

5. Add the following code snippet inside the Main method:


Thread t = new Thread(PrintNumbers);
t.Start();
PrintNumbers();

6. Run the program. The output will be something like the following screenshot:

How it works...
In step 1 and 2, we created a simple console application in C# using .Net Framework version
4.0. Then, in step 3, we included the System.Threading namespace, which contains all the
types needed for the program. Then, we used the using static feature from C# 6.0, which
allows us to use the System.Console type's static methods without specifying the type name.

An instance of a program that is being executed can be referred to as


a process. A process consists of one or more threads. This means that
when we run a program, we always have one main thread that executes
the program code.

In step 4, we defined the PrintNumbers method, which will be used in both the main and
newly created threads. Then, in step 5, we created a thread that runs PrintNumbers. When
we construct a thread, an instance of the ThreadStart or ParameterizedThreadStart
delegate is passed to the constructor. The C# compiler creates this object behind the scenes
when we just type the name of the method we want to run in a different thread. Then, we start
a thread and run PrintNumbers in the usual manner on the main thread.

5
Threading Basics

As a result, there will be two ranges of numbers from 1 to 10 randomly crossing each other.
This illustrates that the PrintNumbers method runs simultaneously on the main thread and
on the other thread.

Pausing a thread
This recipe will show you how to make a thread wait for some time without wasting operating
system resources.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other
prerequisites. The source code for this recipe can be found at BookSamples\Chapter1\
Recipe2.

How to do it...
To understand how to make a thread wait without wasting operating system resources,
perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;

3. Add the following code snippet below the Main method:


static void PrintNumbers()
{
WriteLine("Starting...");
for (int i = 1; i < 10; i++)
{
WriteLine(i);
}
}
static void PrintNumbersWithDelay()
{
WriteLine("Starting...");
for (int i = 1; i < 10; i++)
{
Sleep(TimeSpan.FromSeconds(2));

6
Chapter 1
WriteLine(i);
}
}

4. Add the following code snippet inside the Main method:


Thread t = new Thread(PrintNumbersWithDelay);
t.Start();
PrintNumbers();

5. Run the program.

How it works...
When the program is run, it creates a thread that will execute a code in the
PrintNumbersWithDelay method. Immediately after that, it runs the PrintNumbers
method. The key feature here is adding the Thread.Sleep method call to a
PrintNumbersWithDelay method. It causes the thread executing this code to wait a
specified amount of time (2 seconds in our case) before printing each number. While a thread
sleeps, it uses as little CPU time as possible. As a result, we will see that the code in the
PrintNumbers method, which usually runs later, will be executed before the code in the
PrintNumbersWithDelay method in a separate thread.

Making a thread wait


This recipe will show you how a program can wait for some computation in another thread
to complete to use its result later in the code. It is not enough to use the Thread.Sleep
method because we don't know the exact time the computation will take.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter1\Recipe3.

How to do it...
To understand how a program waits for some computation in another thread to complete in
order to use its result later, perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;

7
Threading Basics
using static System.Console;
using static System.Threading.Thread;

3. Add the following code snippet below the Main method:


static void PrintNumbersWithDelay()
{
WriteLine("Starting...");
for (int i = 1; i < 10; i++)
{
Sleep(TimeSpan.FromSeconds(2));
WriteLine(i);
}
}

4. Add the following code snippet inside the Main method:


WriteLine("Starting...");
Thread t = new Thread(PrintNumbersWithDelay);
t.Start();
t.Join();
WriteLine("Thread completed");

5. Run the program.

How it works...
When the program is run, it runs a long-running thread that prints out numbers and waits
two seconds before printing each number. But, in the main program, we called the t.Join
method, which allows us to wait for the thread t to complete working. When it is complete, the
main program continues to run. With the help of this technique, it is possible to synchronize
execution steps between two threads. The first one waits until another one is complete and
then continues to work. While the first thread waits, it is in a blocked state (as it is in the
previous recipe when you call Thread.Sleep).

Aborting a thread
In this recipe, we will describe how to abort another thread's execution.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter1\Recipe4.

8
Chapter 1

How to do it...
To understand how to abort another thread's execution, perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;
using static System.Console;

3. Using the static System.Threading.Thread, add the following code snippet below
the Main method:
static void PrintNumbersWithDelay()
{
WriteLine("Starting...");
for (int i = 1; i < 10; i++)
{
Sleep(TimeSpan.FromSeconds(2));
WriteLine(i);
}
}

4. Add the following code snippet inside the Main method:


WriteLine("Starting program...");
Thread t = new Thread(PrintNumbersWithDelay);
t.Start();
Thread.Sleep(TimeSpan.FromSeconds(6));
t.Abort();
WriteLine("A thread has been aborted");
Thread t = new Thread(PrintNumbers);
t.Start();
PrintNumbers();

5. Run the program.

9
Threading Basics

How it works...
When the main program and a separate number-printing thread run, we wait for six seconds
and then call a t.Abort method on a thread. This injects a ThreadAbortException
method into a thread, causing it to terminate. It is very dangerous, generally because this
exception can happen at any point and may totally destroy the application. In addition, it is
not always possible to terminate a thread with this technique. The target thread may refuse to
abort by handling this exception by calling the Thread.ResetAbort method. Thus, it is not
recommended that you use the Abort method to close a thread. There are different methods
that are preferred, such as providing a CancellationToken object to cancel a thread
execution. This approach will be described in Chapter 3, Using a Thread Pool.

Determining a thread state


This recipe will describe the possible states a thread could have. It is useful to get information
about whether a thread is started yet or whether it is in a blocked state. Note that because a
thread runs independently, its state could be changed at any time.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter1\Recipe5.

How to do it...
To understand how to determine a thread state and acquire useful information about it,
perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;

3. Add the following code snippet below the Main method:


static void DoNothing()
{
Sleep(TimeSpan.FromSeconds(2));
}

static void PrintNumbersWithStatus()

10
Chapter 1
{
WriteLine("Starting...");
WriteLine(CurrentThread.ThreadState.ToString());
for (int i = 1; i < 10; i++)
{
Sleep(TimeSpan.FromSeconds(2));
WriteLine(i);
}
}

4. Add the following code snippet inside the Main method:


WriteLine("Starting program...");
Thread t = new Thread(PrintNumbersWithStatus);
Thread t2 = new Thread(DoNothing);
WriteLine(t.ThreadState.ToString());
t2.Start();
t.Start();
for (int i = 1; i < 30; i++)
{
WriteLine(t.ThreadState.ToString());
}
Sleep(TimeSpan.FromSeconds(6));
t.Abort();
WriteLine("A thread has been aborted");
WriteLine(t.ThreadState.ToString());
WriteLine(t2.ThreadState.ToString());

5. Run the program.

How it works...
When the main program starts, it defines two different threads; one of them will be
aborted and the other runs successfully. The thread state is located in the ThreadState
property of a Thread object, which is a C# enumeration. At first, the thread has a
ThreadState.Unstarted state. Then, we run it and assume that for the duration of
30 iterations of a cycle, the thread will change its state from ThreadState.Running to
ThreadState.WaitSleepJoin.

Note that the current Thread object is always accessible through


the Thread.CurrentThread static property.

11
Threading Basics

If this does not happen, just increase the number of iterations. Then, we abort the first
thread and see that now it has a ThreadState.Aborted state. It is also possible that the
program will print out the ThreadState.AbortRequested state. This illustrates, very well,
the complexity of synchronizing two threads. Keep in mind that you should not use thread
abortion in your programs. I've covered it here only to show the corresponding thread state.

Finally, we can see that our second thread t2 was completed successfully and now has a
ThreadState.Stopped state. There are several other states, but they are partly deprecated
and not as useful as those we examined.

Thread priority
This recipe will describe the different options for thread priority. Setting a thread priority
determines how much CPU time a thread will be given.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter1\Recipe6.

How to do it...
To understand the workings of thread priority, perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;
using static System.Diagnostics.Process;

3. Add the following code snippet below the Main method:


static void RunThreads()
{
var sample = new ThreadSample();

var threadOne = new Thread(sample.CountNumbers);


threadOne.Name = "ThreadOne";
var threadTwo = new Thread(sample.CountNumbers);
threadTwo.Name = "ThreadTwo";

threadOne.Priority = ThreadPriority.Highest;

12
Chapter 1
threadTwo.Priority = ThreadPriority.Lowest;
threadOne.Start();
threadTwo.Start();

Sleep(TimeSpan.FromSeconds(2));
sample.Stop();
}

class ThreadSample
{
private bool _isStopped = false;

public void Stop()


{
_isStopped = true;
}

public void CountNumbers()


{
long counter = 0;

while (!_isStopped)
{
counter++;
}

WriteLine($"{CurrentThread.Name} with " +


$"{CurrentThread.Priority,11} priority " +
$"has a count = {counter,13:N0}");
}
}

4. Add the following code snippet inside the Main method:


WriteLine($"Current thread priority: {CurrentThread.Priority}");
WriteLine("Running on all cores available");
RunThreads();
Sleep(TimeSpan.FromSeconds(2));
WriteLine("Running on a single core");
GetCurrentProcess().ProcessorAffinity = new IntPtr(1);
RunThreads();

5. Run the program.

13
Threading Basics

How it works...
When the main program starts, it defines two different threads. The first one, threadOne,
has the highest thread priority ThreadPriority.Highest, while the second one, that
is threadTwo, has the lowest ThreadPriority.Lowest priority. We print out the main
thread priority value and then start these two threads on all available cores. If we have more
than one computing core, we should get an initial result within two seconds. The highest
priority thread should calculate more iterations usually, but both values should be close.
However, if there are any other programs running that load all the CPU cores, the situation
could be quite different.

To simulate this situation, we set up the ProcessorAffinity option, instructing the


operating system to run all our threads on a single CPU core (number 1). Now, the results
should be very different, and the calculations will take more than two seconds. This happens
because the CPU core runs mostly the high-priority thread, giving the rest of the threads very
little time.

Note that this is an illustration of how an operating system works with thread prioritization.
Usually, you should not write programs relying on this behavior.

Foreground and background threads


This recipe will describe what foreground and background threads are and how setting this
option affects the program's behavior.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter1\Recipe7.

How to do it...
To understand the effect of foreground and background threads on a program, perform the
following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;

14
Chapter 1

3. Add the following code snippet below the Main method:


class ThreadSample
{
private readonly int _iterations;

public ThreadSample(int iterations)


{
_iterations = iterations;
}
public void CountNumbers()
{
for (int i = 0; i < _iterations; i++)
{
Sleep(TimeSpan.FromSeconds(0.5));
WriteLine($"{CurrentThread.Name} prints {i}");
}
}
}

4. Add the following code snippet inside the Main method:


var sampleForeground = new ThreadSample(10);
var sampleBackground = new ThreadSample(20);

var threadOne = new Thread(sampleForeground.CountNumbers);


threadOne.Name = "ForegroundThread";
var threadTwo = new Thread(sampleBackground.CountNumbers);
threadTwo.Name = "BackgroundThread";
threadTwo.IsBackground = true;

threadOne.Start();
threadTwo.Start();

5. Run the program.

How it works...
When the main program starts, it defines two different threads. By default, a thread that we
create explicitly is a foreground thread. To create a background thread, we manually set the
IsBackground property of the threadTwo object to true. We configure these threads in a
way that the first one will be completed faster, and then we run the program.

15
Threading Basics

After the first thread is complete, the program shuts down and the background thread is
terminated. This is the main difference between the two: a process waits for all the foreground
threads to complete before finishing the work, but if it has background threads, they just
shut down.

It is also important to mention that if a program defines a foreground thread that does not get
completed; the main program does not end properly.

Passing parameters to a thread


This recipe will describe how to provide code that we run in another thread with the required
data. We will go through the different ways to fulfill this task and review common mistakes.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter1\Recipe8.

How to do it...
To understand how to pass parameters to a thread, perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;

3. Add the following code snippet below the Main method:


static void Count(object iterations)
{
CountNumbers((int)iterations);
}

static void CountNumbers(int iterations)


{
for (int i = 1; i <= iterations; i++)
{
Sleep(TimeSpan.FromSeconds(0.5));
WriteLine($"{CurrentThread.Name} prints {i}");
}

16
Chapter 1
}

static void PrintNumber(int number)


{
WriteLine(number);
}

class ThreadSample
{
private readonly int _iterations;

public ThreadSample(int iterations)


{
_iterations = iterations;
}
public void CountNumbers()
{
for (int i = 1; i <= _iterations; i++)
{
Sleep(TimeSpan.FromSeconds(0.5));
WriteLine($"{CurrentThread.Name} prints {i}");
}
}
}

4. Add the following code snippet inside the Main method:


var sample = new ThreadSample(10);

var threadOne = new Thread(sample.CountNumbers);


threadOne.Name = "ThreadOne";
threadOne.Start();
threadOne.Join();

WriteLine("--------------------------");

var threadTwo = new Thread(Count);


threadTwo.Name = "ThreadTwo";
threadTwo.Start(8);
threadTwo.Join();

WriteLine("--------------------------");

var threadThree = new Thread(() => CountNumbers(12));


threadThree.Name = "ThreadThree";

17
Threading Basics
threadThree.Start();
threadThree.Join();
WriteLine("--------------------------");

int i = 10;
var threadFour = new Thread(() => PrintNumber(i));
i = 20;
var threadFive = new Thread(() => PrintNumber(i));
threadFour.Start();
threadFive.Start();

5. Run the program.

How it works...
When the main program starts, it first creates an object of the ThreadSample
class, providing it with a number of iterations. Then, we start a thread with the object's
CountNumbers method. This method runs in another thread, but it uses the number 10,
which is the value that we passed to the object's constructor. Therefore, we just passed
this number of iterations to another thread in the same indirect way.

There's more…
Another way to pass data is to use the Thread.Start method by accepting an object that
can be passed to another thread. To work this way, a method that we started in another
thread must accept one single parameter of the type object. This option is illustrated by
creating a threadTwo thread. We pass 8 as an object to the Count method, where it is
cast to an integer type.

The next option involves the use of lambda expressions. A lambda expression defines a
method that does not belong to any class. We create such a method that invokes another
method with the arguments needed and start it in another thread. When we start the
threadThree thread, it prints out 12 numbers, which are exactly the numbers we passed
to it via the lambda expression.

The use of lambda expressions involves another C# construct named closure. When we
use any local variable in a lambda expression, C# generates a class and makes this variable
a property of this class. So, actually, we do the same thing as in the threadOne thread, but
we do not define the class ourselves; the C# compiler does this automatically.

This could lead to several problems; for example, if we use the same variable from several
lambdas, they will actually share this variable value. This is illustrated by the previous
example where, when we start threadFour and threadFive, they both print 20 because
the variable was changed to hold the value 20 before both threads were started.

18
Chapter 1

Locking with a C# lock keyword


This recipe will describe how to ensure that when one thread uses some resource, another
does not simultaneously use it. We will see why this is needed and what the thread safety
concept is all about.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter1\Recipe9.

How to do it...
To understand how to use the C# lock keyword, perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;
using static System.Console;

3. Add the following code snippet below the Main method:


static void TestCounter(CounterBase c)
{
for (int i = 0; i < 100000; i++)
{
c.Increment();
c.Decrement();
}
}

class Counter : CounterBase


{
public int Count { get; private set; }

public override void Increment()


{
Count++;
}

public override void Decrement()

19
Threading Basics
{
Count--;
}
}

class CounterWithLock : CounterBase


{
private readonly object _syncRoot = new Object();

public int Count { get; private set; }

public override void Increment()


{
lock (_syncRoot)
{
Count++;
}
}

public override void Decrement()


{
lock (_syncRoot)
{
Count--;
}
}
}

abstract class CounterBase


{
public abstract void Increment();

public abstract void Decrement();


}

4. Add the following code snippet inside the Main method:


WriteLine("Incorrect counter");

var c = new Counter();

var t1 = new Thread(() => TestCounter(c));


var t2 = new Thread(() => TestCounter(c));
var t3 = new Thread(() => TestCounter(c));
t1.Start();

20
Chapter 1
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();

WriteLine($"Total count: {c.Count}");


WriteLine("--------------------------");

WriteLine("Correct counter");

var c1 = new CounterWithLock();

t1 = new Thread(() => TestCounter(c1));


t2 = new Thread(() => TestCounter(c1));
t3 = new Thread(() => TestCounter(c1));
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();
WriteLine($"Total count: {c1.Count}");

5. Run the program.

How it works...
When the main program starts, it first creates an object of the Counter class. This class
defines a simple counter that can be incremented and decremented. Then, we start three
threads that share the same counter instance and perform an increment and decrement in
a cycle. This leads to nondeterministic results. If we run the program several times, it will
print out several different counter values. It could be 0, but mostly won't be.

This happens because the Counter class is not thread-safe. When several threads access
the counter at the same time, the first thread gets the counter value 10 and increments it to
11. Then, a second thread gets the value 11 and increments it to 12. The first thread gets the
counter value 12, but before a decrement takes place, a second thread gets the counter value
12 as well. Then, the first thread decrements 12 to 11 and saves it into the counter, and the
second thread simultaneously does the same. As a result, we have two increments and only
one decrement, which is obviously not right. This kind of a situation is called a race condition
and is a very common cause of errors in a multithreaded environment.

21
Threading Basics

To make sure that this does not happen, we must ensure that while one thread works with the
counter, all other threads wait until the first one finishes the work. We can use the lock keyword
to achieve this kind of behavior. If we lock an object, all the other threads that require an access
to this object will wait in a blocked state until it is unlocked. This could be a serious performance
issue and later, in Chapter 2, Thread Synchronization, you will learn more about this.

Locking with a Monitor construct


This recipe illustrates another common multithreaded error called a deadlock. Since a
deadlock will cause a program to stop working, the first piece in this example is a new
Monitor construct that allows us to avoid a deadlock. Then, the previously described
lock keyword is used to get a deadlock.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter1\Recipe10.

How to do it...
To understand the multithreaded error deadlock, perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;

3. Add the following code snippet below the Main method:


static void LockTooMuch(object lock1, object lock2)
{
lock (lock1)
{
Sleep(1000);
lock (lock2);
}
}

4. Add the following code snippet inside the Main method:


object lock1 = new object();

22
Chapter 1
object lock2 = new object();

new Thread(() => LockTooMuch(lock1, lock2)).Start();

lock (lock2)
{
Thread.Sleep(1000);
WriteLine("Monitor.TryEnter allows not to get stuck, returning
false after a specified timeout is elapsed");
if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(5)))
{
WriteLine("Acquired a protected resource succesfully");
}
else
{
WriteLine("Timeout acquiring a resource!");
}
}

new Thread(() => LockTooMuch(lock1, lock2)).Start();

WriteLine("----------------------------------");
lock (lock2)
{
WriteLine("This will be a deadlock!");
Sleep(1000);
lock (lock1)
{
WriteLine("Acquired a protected resource succesfully");
}
}

5. Run the program.

How it works...
Let's start with the LockTooMuch method. In this method, we just lock the first object, wait
for a second, and then lock the second object. Then, we start this method in another thread
and try to lock the second object and then the first object from the main thread.

If we use the lock keyword like in the second part of this demo, there will be a deadlock.
The first thread holds a lock on the lock1 object and waits while the lock2 object gets
free; the main thread holds a lock on the lock2 object and waits for the lock1 object to
become free, which will never happen in this situation.

23
Threading Basics

Actually, the lock keyword is syntactic sugar for the Monitor class usage. If we were to
disassemble code with lock, we would see that it turns into the following code snippet:
bool acquiredLock = false;
try
{
Monitor.Enter(lockObject, ref acquiredLock);

// Code that accesses resources that are protected by the lock.

}
finally
{
if (acquiredLock)
{
Monitor.Exit(lockObject);
}
}

Therefore, we can use the Monitor class directly; it has the TryEnter method, which
accepts a timeout parameter and returns false if this timeout parameter expires before
we can acquire the resource protected by lock.

Handling exceptions
This recipe will describe how to handle exceptions in other threads properly. It is very
important to always place a try/catch block inside the thread because it is not possible
to catch an exception outside a thread's code.

Getting ready
To work through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter1\Recipe11.

How to do it...
To understand the handling of exceptions in other threads, perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


2. In the Program.cs file, add the following using directives:
using System;
using System.Threading;

24
Chapter 1
using static System.Console;
using static System.Threading.Thread;

3. Add the following code snippet below the Main method:


static void BadFaultyThread()
{
WriteLine("Starting a faulty thread...");
Sleep(TimeSpan.FromSeconds(2));
throw new Exception("Boom!");
}

static void FaultyThread()


{
try
{
WriteLine("Starting a faulty thread...");
Sleep(TimeSpan.FromSeconds(1));
throw new Exception("Boom!");
}
catch (Exception ex)
{
WriteLine($"Exception handled: {ex.Message}");
}
}

4. Add the following code snippet inside the Main method:


var t = new Thread(FaultyThread);
t.Start();
t.Join();

try
{
t = new Thread(BadFaultyThread);
t.Start();
}
catch (Exception ex)
{
WriteLine("We won't get here!");
}

5. Run the program.

25
Threading Basics

How it works...
When the main program starts, it defines two threads that will throw an exception. One of
these threads handles an exception, while the other does not. You can see that the second
exception is not caught by a try/catch block around the code that starts the thread. So, if
you work with threads directly, the general rule is to not throw an exception from a thread, but
to use a try/catch block inside a thread code instead.

In the older versions of .NET Framework (1.0 and 1.1), this behavior was different and
uncaught exceptions did not force an application shutdown. It is possible to use this policy
by adding an application configuration file (such as app.config) that contains the following
code snippet:
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1" />
</runtime>
</configuration>

26
Thread Synchronization
2
In this chapter, we will describe some of the common techniques of working with shared
resources from multiple threads. You will learn the following recipes:

f Performing basic atomic operations


f Using the Mutex construct
f Using the SemaphoreSlim construct
f Using the AutoResetEvent construct
f Using the ManualResetEventSlim construct
f Using the CountDownEvent construct
f Using the Barrier construct
f Using the ReaderWriterLockSlim construct
f Using the SpinWait construct

Introduction
As we saw in Chapter 1, Threading Basics, it is problematic to use a shared object
simultaneously from several threads. However, it is very important to synchronize those threads
so that they perform operations on that shared object in a proper sequence. In the Locking with
a C# lock keyword recipe, we faced a problem called the race condition. The problem occurred
because the execution of those multiple threads was not synchronized properly. When one
thread performs increment and decrement operations, the other threads must wait for their
turn. Organizing threads in such a way is often referred to as thread synchronization.

There are several ways to achieve thread synchronization. First, if there is no shared object,
there is no need for synchronization at all. Surprisingly, it is very often the case that we can
get rid of complex synchronization constructs by just redesigning our program and removing
a shared state. If possible, just avoid using a single object from several threads.

27
Thread Synchronization

If we must have a shared state, the second approach is to use only atomic operations. This
means that an operation takes a single quantum of time and completes at once, so no other
thread can perform another operation until the first operation is complete. Therefore, there is
no need to make other threads wait for this operation to complete and there is no need to use
locks; this in turn, excludes the deadlock situation.

If this is not possible and the program's logic is more complicated, then we have to use
different constructs to coordinate threads. One group of these constructs puts a waiting
thread into a blocked state. In a blocked state, a thread uses as little CPU time as possible.
However, this means that it will include at least one so-called context switch—the thread
scheduler of an operating system will save the waiting thread's state and switch to another
thread, restoring its state by turn. This takes a considerable amount of resources; however,
if the thread is going to be suspended for a long time, it is good. These kind of constructs
are also called kernel-mode constructs because only the kernel of an operating system is
able to stop a thread from using CPU time.

In case, we have to wait for a short period of time, it is better to simply wait than switch
the thread to a blocked state. This will save us the context switch at the cost of some
wasted CPU time while the thread is waiting. Such constructs are referred to as user-mode
constructs. They are very lightweight and fast, but they waste a lot of CPU time in case a
thread has to wait for long.

To use the best of both worlds, there are hybrid constructs; these try to use user-mode
waiting first, and then, if a thread waits long enough, it switches to the blocked state,
saving CPU resources.

In this chapter, we will look through the aspects of thread synchronization. We will cover how
to perform atomic operations and how to use the existing synchronization constructs included
in .NET Framework.

Performing basic atomic operations


This recipe will show you how to perform basic atomic operations on an object to prevent the
race condition without blocking threads.

Getting ready
To step through this recipe, you will need Visual Studio 2015. There are no other prerequisites.
The source code for this recipe can be found at BookSamples\Chapter2\Recipe1.

How to do it...
To understand basic atomic operations, perform the following steps:

1. Start Visual Studio 2015. Create a new C# console application project.


28
Other documents randomly have
different content
A few days later, however, Captain Conway called again, and as on
this occasion Emma happened to be in the drawing-room with her
sister, she was obliged to submit to his company; but she remained
almost as silent as before, and would scarcely raise her eyes.
On his departure, Jane again turned on her and vowed that she
would soon bring her to her senses by writing to Robert.
"He will send you such a message as you will be bound to obey," she
said. "We have done all that could be thought of to fix one of you,
and now when there is a chance of your getting settled you are all
for throwing it away! You put me quite out of patience with you!"
Robert answered the letter in person; and, to Jane's amazement,
declared positively that he was not going to have Emma thrown
away on any half-pay officer; and that he had so much information
against Captain Conway, he would hunt him out of the
neighbourhood.
On the following morning, however, when he drove into A——, he
found that that gentleman, having caught sight of him on the stage
coach the previous afternoon, had hastily cleared out, taking Mrs.
Burton along with him.
It then transpired that the two had been in collusion; and that Mrs.
Burton, believing Emma to be the heiress of her aunt, had
introduced Captain Conway to her, on the understanding that she
was to receive a substantial sum on the consummation of his
marriage with her.
Jane was deeply mortified at having allowed herself to be mixed up
with such people; and it was in a very chastened frame of mind that
Robert left her, on his return to Croydon, promising to come back in
August for a fortnight's holiday.
CHAPTER XII
Mr. Howard had been but a short time with the Osbornes when he
was obliged to confess that he had made a mistake in coming.
A man of singular charm of manner, eminently gifted for social
success, he had as little vanity as well might be; and his devotion to
literature engendered in him a sort of absent-mindedness which
rendered him unconscious of things which were sufficiently obvious
to others.
He could scarcely himself have said what now opened his eyes in
some measure to the nature of Miss Osborne's regard for him; for
never before had it occurred to him that she entertained anything
beyond an ordinary friendship—the very fact of her occasional
efforts to flirt with him only confirming his confidence in her
indifference and merely contributing to his amusement.
He had been but little pleased by her incursion into his dinner party;
but had attributed it to her lack of variety in a dull neighbourhood
and to the influence of Miss Carr, of whom he entertained but a
slight opinion. The jealousy of Emma, which she had betrayed at the
ball, he believed to be entirely owing to her brother's admiration of
her—the connection being such as she could scarcely be expected to
advocate.
The knowledge of her feelings occasioned him so much regret, that
he would fain have left Italy then and there; but in view of the
urgent invitations he had received from Lady Osborne and her son,
this was scarcely possible. For the moment at least, he must remain
where he was.
He began at once, however, to cast about for some excuse to
shorten his stay; and presently urged his desire to prosecute his
travels in Spain and Portugal. He had long desired to journey there,
and there was now no impediment to his doing so, as his cousin,
whose bedside he had attended, had bequeathed him a large
fortune, independently of the handsome property to which he had
succeeded as heir-presumptive; but, to his surprise, Lady Osborne
withstood him, with flushed cheeks and tears in her eyes.
"Do not desert us the moment you have come," she said; "Osborne
has seemed so much more composed since you joined us—I never
before knew him to be so disquieted as he has been. I cannot but
admire Miss Watson's conduct—had she chosen to accept him,
nothing could have prevented the marriage. I had scarcely realised
how serious his passion was until the night of the ball—after she had
left us. He was quite in despair."
"I understand she is shortly to be married."
"Have you told Osborne?"
"No. He has not mentioned her name to me."
"Am I at liberty to tell him?"
"Certainly, madam; what object could be served in concealing it?
Osborne could scarcely conceive the idea of rushing home to present
a pistol at her lover's head!"
Later on in the evening, Lord Osborne entered the private sitting-
room of his late tutor, and said abruptly—
"My mother has informed me of Miss Watson's engagement. To
whom is she to be married?"
"That I cannot tell you."
"How came you to know?"
"Musgrave told me.'
"Musgrave! I would place monstrous little faith in anything he said!"
"He was certainly never my friend, but I understood him to be
yours," replied Mr. Howard, coldly.
"What can a man do in that delectable neighbourhood?—He helps
one to get through the time. I dare swear he made the whole thing
up!" So saying, Lord Osborne swung out of the room.
He had not been long gone when there was a timid knock, and Miss
Osborne entered with a book in her hand.
Mr. Howard rose and placed a chair for her; but did not sit down
himself.
"I came to ask you if you would be so very good as to help me with
this passage in Dante's Inferno," she said.
He read it at once without any hesitation, as the portion indicated
presented no special difficulty that he could see; and he was
constrained to wonder wherefore she had selected it—the truth
being that she had opened the volume at random.
"I have just heard from Lady Osborne that Miss Watson is about to
be married."
In spite of himself, he was obliged to smile.
"I regret that I have nothing to add to this thunderbolt!"
"You are quite sure that she is to be married?"
He was aware that she was watching him narrowly, and both his
face and voice were entirely under control as he replied—
"I see no reason to doubt Mr. Musgrave's statement. He was just
coming from the Rectory, and I know he was intimate with them."
"He was altogether mad with her for refusing to dance with him at
our ball—Fanny Carr told me so."
Mr. Howard looked startled for a moment; and she proceeded—
"Fanny thought it showed a great want of breeding on her part to be
so insolent to a guest of ours—she is not in a position to be
disdainful of anyone—I should never think of calling her a lady."
She received no answer to this.
"Oh, I know you were vastly in love with her—I was quite expecting
to have to congratulate you!"—with an attempt at archness.
Mr. Howard contented himself with bowing.
"I thought her rather handsome myself; but several gentlemen said
to me that they did not at all think her anything out of the common."
This again was received in silence; and Julia Osborne, considerably
mortified, and perfectly aware of Lady Osborne's displeasure, should
she learn of her adventure, thought it best to retire to her room.
A few days later they were joined by Lord Edward Sothern, to whom
Miss Osborne turned her attentions, and with much greater prospect
of ultimate success.
This, however, was not at all what she desired; but to inflict some
gentle damage on an unimpressive heart, which she should
presently be called upon to repair. In vain was the snare laid; and
she was shortly engaged in a flirtation which obliged Lady Osborne
to compel her to accept the proposal which speedily followed, and
was urged with insistence.
Julia Osborne was not a little incensed at the turn affairs had taken;
and believing Mr. Howard to be the cause of all the mischief, felt that
she had been barbarously used. Her resentment grew with
reflection; and for a time nothing could appease her, although it was
incumbent on her to dissemble her feelings. All this, however, had
the salutary effect of estranging her from the first object of her
affections; and by degrees the good-humour and attentions of her
lover reconciled her to the hardship of her fate.
CHAPTER XIII
As the period for which the Osbornes had engaged a suite of
apartments (in an old palace) had drawn to a close, they proceeded
with their guests by easy stages to Florence.
Mr. Howard was now Lady Osborne's constant companion, as they
rambled about amongst the old churches, and through the galleries,
so rich in the masterpieces of the world. He was much more
attached to her than to any member of the family, always finding in
her a congenial companion. She was an amiable, intelligent, elegant
woman, greatly superior to her son and daughter, as well by nature
as cultivation.
Her beauty was wonderfully preserved; her fair hair untouched by
time; her eyes undimmed; and a bright colour glowing in her cheeks
as she walked along under the perfect blue of the Italian sky. As
they turned down the "Way of the Beautiful Ladies," he could not
but acknowledge how well she fulfilled the tradition.
"You are very silent, Arthur," she said.
He looked at her with a smile in his eyes, and made some brief
answer.
Never before had she addressed him by his christian name, and he
was at once gratified by a friendship which was sincere enough to
desire the intimacy; and disappointed that the music of his name
had not sounded for him on the lips of another, whose image he was
as yet unable to banish from his heart.
As though divining something of the trend of his thought, she began
to speak of Emma; continuing—
"I thought her a perfect lady—I could find no want of breeding in
her. Modest, yet confident, as one used to Society; refined, yet
without affectation. When I think of the difference between her and
the other members of her family, whom I have noticed at the
Assembly balls, I am forced to the conclusion that her father must
have married very much beneath him. It must be trying for her,
when she has been brought up so differently, to be obliged to live
with them now."
"She seems to be attached to her eldest sister."
"She impressed me much more favourably than her other sisters,
whose conduct has attracted my attention on different occasions—
she is too simple to be accused of vulgarity."
They walked along in silence for a brief space; and then Lady
Osborne continued—
"Is it not very much to be deplored that men so seldom ask for
anything beyond youth and beauty?—so seldom consider merit, or
suitability? How often have not men disregarded every indication of
personal qualities that would have assured their happiness, and
turned aside after the first pretty face that came in their way? It is a
sort of blindness—an absence of penetration—which must bring
ultimate regret. Do you remember the Sacristan, in Santa Croce,
telling us of the priceless frescoes of Giotto that lay hidden under
the whitewash on the walls of the Chapel of the Bardi della Liberta?
It made me think of how often so much lies hidden from us by an
even slighter veil—a gossamer so slender that we may afterwards
come to wonder what obstacle it could have presented to us!"
Her companion looked at her in wonder, not unmixed with sorrow,
though the appeal in her voice held no meaning for him; and he was
constrained to walk along in silence at her side.
Later on, as she sat beneath Botticelli's Fortitude, with her hand on
her parasol, the likeness between them struck him with almost a
sense of dismay. Her bright colour had faded, and there was a look
of weariness and lassitude on her face. As in the picture, it was the
face of one who had suffered, and would yet again suffer, before she
had laid her head on the quiet pillow of her grave.
* * * * * *
Towards the end of May, the Osbornes returned to London to
prepare for Miss Osborne's wedding, whilst Mr. Howard went on his
way to Spain.
CHAPTER XIV
The Watsons returned to Croydon in October; and a few weeks later,
Mrs. Watson, finding the resignation of second mourning eminently
becoming, sent out invitations for a party.
Emma was very sensible of the want of propriety in having company
within a year of her father's death; but Robert welcomed the
arrangement, as he was anxious to show attention to some new and
important clients.
About a week before the entertainment was to take place, Lord
Osborne called. He was shown into the drawing-room where Emma
was working at her embroidery; while Jane sat near her, making out
a list of the dishes that would be necessary for the supper.
It was with a sinking heart that Emma rose and curtsied to him. She
had hoped that he had forgotten her; and his persistence in once
more following her could only serve to aggravate the difficulty of her
position. Jane was not a little agitated at finding herself, for the first
time in her life, in the society of a man of his position; and was also
a good deal disconcerted by having thrown her second best tippet
round her shoulders, when her best would have been so much more
suitable to such an important occasion.
As Emma remained silent, she believed it to be incumbent on her to
express her sense of the honour he had done them in calling,
enquiring with immense affability for Lady Osborne and Lady Edward
Sothern.
Emma then enquired for Mrs. Blake and Charles, and learned that
the latter was head of his class at school, and was grown a
monstrous fine fellow. Lord Osborne then added that Mr. Howard
was not yet returned from Spain.
"How do you like Croydon, Miss Watson?" he continued. "I always
thought it famously dull myself."
"There are some pleasant walks towards the country," she began,
when she was hastily interrupted by Jane.
"Oh! I assure you, Lord Osborne, there is an immense deal of
fashion in Croydon! Many of the families live in the first style—and as
for sociability, there are few places to equal it! When not in
mourning, we are in company nearly every evening!"
Lord Osborne looked not a little astonished; then, after a short
pause, turning to Emma, said—
"I am glad to hear you are taking exercise. Do not you now wear
half-boots?"
Emma began to laugh; and believing he must have said something
witty, he joined in very heartily.
At this moment, Robert entered the room. He had not expected to
find Lord Osborne there; but Emma was gratified by the quiet
manner in which he received him. Taking the conversation into his
own hands, he discussed the harvest; the French; the incapacity of
the Government (that unfailing source of gratification to those who
govern not); and a new play, which a friend of his had seen in
London. Emma had never before heard him talk so well; and yet she
was aware that there was something wanting in cordiality; but Lord
Osborne was apparently very well satisfied to be spared the fatigue
of exercising his brain.
Jane, however, listened with ill-concealed impatience; and when, at
length, Robert paused, she lost no time in striking in, and began—
"We are arranging to have a little company, my lord——"
But Robert was quite equal to playing the husband; and the instant
displeasure of his eye froze the invitation which was hovering on her
lips.
"Mr. Musgrave mentioned something of the sort to me," replied Lord
Osborne, colouring slightly. "I should be very much honoured,
madam, if you would be so good as to include me."
The request was made with a sort of simple shyness that made it
impossible to be refused; but as Robert returned to the drawing-
room, after seeing him out, his face was clouded.
"I am sure you are too sensible, Emma," he said, "to desire to have
Lord Osborne dangling after you. It will not be possible for him to
marry you. It will only occasion spiteful gossip; and perhaps prevent
your getting fixed."
"I assure you, Robert," replied Emma, blushing, "that not for
anything in the world would I encourage him—I sincerely hope that
he will not continue to call." With that, she left the room.
Jane had been watching her, with shrewd eyes, in silence.
"I declare I never met a girl like her!" she exclaimed. "I am as
certain as anything that she is not wanting to have him! But mark
my words, Robert, Lord Osborne is in earnest! He is not for flirting at
all. And, unless she is a born fool, Emma will be 'my lady'!"
* * * * * *
On the night of the party, Augusta was allowed to remain up for
half-an-hour; Sam had got leave to join them; and Lord Osborne and
Mr. Musgrave were amongst the first arrivals.
After the usual civilities, Lord Osborne sat down by Emma; and as
the guests began to arrive in quick succession, and were not long in
being informed by Jane as to his quality, inquisitive glances were
constantly directed towards them. Seeing this, Emma presently
excused herself, and went to sit by a lady to whom she had been
previously introduced; but in a few moments he had followed her.
She then presented him to the lady, who was only too pleased to
form the acquaintance; and moved on to speak to a pretty girl who
was sitting somewhat apart, and who appeared to know as few
people as Emma herself. But again he came after her; and although
she did her best to engage the two in conversation, the former was
so shy, and the latter so dull, that it appeared to her as though they
had simultaneously embarked on a game as to which should limit
their observations to the fewest words of one syllable. In response
to an imploring eye, Sam came over, and she introduced them; and
shortly afterwards they were joined by little Augusta. Lord Osborne
was at once attracted by the pretty child; and, lifting her up on his
knee, presented her with his silver comfit-box. It was soon time for
her to retire, and Emma took her, herself, up to her room, remaining
with her until Sam was sent in search of her.
As she was coming down stairs, with her hand on his arm, she
paused and said earnestly—
"Sam—cannot you help me?"
He remained silent, and she continued: "You can have no conception
how I have been suffering from Jane's boasting—and now that Lord
Osborne has come, it will be worse than ever! Could not you
persuade Robert to forbid him the house?"
"Are you quite sure, Emma, that you know your own heart? Should
he be sent away, can you be certain that you will not be regretting
it?"
"Quite sure and quite certain!" she replied, smiling.
"Is there anyone else, then, that you care for?"
She blushed deeply, and tears gathered in her eyes.
"There—my love!" he said, gently. "I should not have asked you."
When they re-entered the drawing-room, Lord Osborne was at once
at her side. The card-table was being set, and he was anxious to
arrange a party for whist, which should include Emma and himself.
Robert, however, interposed by coming forward and requesting his
sister to be so kind as to sit beside old Lady Brown, and show her
how to play speculation. "Did I hear you say 'whist,' my lord?—this
way, if you will be good enough."
At supper, Lord Osborne found himself separated by the length of
the room from the object of his admiration; and when he
endeavoured to engage her afterwards as his partner, Sam had
already secured her for another table.
Jane was perfectly aware of the manoeuvres of her husband and
brother, and was not a little entertained by them. "It will only serve
to inflame Lord Osborne," she thought to herself. "They could not be
playing her cards better!"
* * * * * *
Sam was obliged to leave them on the following day; but, before
going, he urged Robert to put a stop to Lord Osborne calling.
"It is not so simple as you think, Sam," replied his brother. "I shall
certainly not give him any encouragement—still less, allow Emma to
be thrown at his head. But Jane will have it that he is violently in
love with Emma, and quite determined to marry her. If such should
be the case, I would not be justified in standing in her way—it would
be a very fine match for her."
"I assure you she does not desire it."
"Emma is a good girl—I am perfectly satisfied with her conduct; but,
of course, if Lord Osborne intends to ask her, everything will be quite
different—she will not think of him in the same way. She is now
afraid of being made to appear foolish."
With this, Sam had perforce to be satisfied; and he was at least
confident that Robert would secure his sister from any impertinence.
CHAPTER XV
Mrs. Robert Watson having announced her emancipation from the
trammels of woe, invitations poured in, fast and thick, in all of which
Emma was specially included.
It was fine, bright weather, with the pleasantest frost; and Emma
was able to take out Augusta nearly every morning for a walk. To
her dismay, however, she found herself frequently joined by Lord
Osborne, who had taken rooms in a neighbouring inn; and she
appealed in vain to her sister to accompany them, or to take charge
of the child herself.
Matters were brought to a head by Jane, who deliberately informed
Lord Osborne one morning when he called, of the direction in which
Emma had gone. She herself had sent her some little distance
beyond the town, in order to enquire for an old servant who was ill.
The result was, that as Emma was turning but the first corner on her
return home, she came face to face with Lord Osborne.
She replied to his greeting as coldly as might be; and was
endeavouring to proceed on her way, when she was brought to a
standstill by his informing her that Mrs. Watson had been so good as
to indicate to him where he might find her. "She was particularly
kind," he said. "I am very much obliged to her—the more so that I
have been missing you for so many mornings."
Emma's eyes had been fixed on the ground, but she now suddenly
raised them. His face was slightly flushed, and his whole manner
betrayed confidence.
Pale with anger, and holding Augusta's hand tightly, she confronted
him.
"Lord Osborne, I am alone and unprotected," she said. "You must
surely see that your attentions only cause me distress. Be good
enough to let me proceed on my way, without accompanying me."
"Mrs. Watson has given me her permission to escort you home."
"My sister-in-law has no conception of her duty to me."
"Believe me, Miss Watson, my intentions are entirely honourable.
You have no reason to treat me with such coldness. My whole desire
is to make you my wife—if you will honour me by accepting me."
Emma curtsied.
"I cannot possibly accept you, my lord—I beseech you to accept this
answer as final—I can never be your wife!—but, believe me, I am
deeply sensible to the honour you have done me."
"What reason can you have for refusing me? Do not be so hasty!
You do not perhaps know me well enough. I will wait—I will be
patient—if you will only give me one word of hope!"
"My lord, I cannot!"
"You cannot?—why cannot you?"
Emma remained silent, but she was walking onward, the while he
kept at her side.
"Miss Emma! why do not you speak?"
She could find no reply.
"I know I am a dull fellow—but I love you so much! There is not
anything I would not do for you! Could not you care for me a little?"
"No, my lord."
"If you were only married to me, you would care for me!—you could
not but care for me if we were married—I would love you so much!"
Emma wept.
"Why do you make my aunt cry? Why do not you go away?" asked
little Augusta, looking over at him reproachfully.
"It needs a child to point out my obvious duty," he said bitterly; and,
turning back, he strode away.
Augusta remained silent for several minutes, and then said—
"Is not a lord nicer than a gentleman?"
Emma was obliged to smile.
"Shall not you marry him after a while?" she continued.
"Would you like to marry him, Augusta?"
"No," replied the child, after a little hesitation; "it always seems a
long time when he is there."
On their return home, Jane herself opened the door and, fixing her
eyes on Emma, said—
"Has Lord Osborne asked you?"
Emma admitted it.
"Well, you have accepted him?"
"No."
"You have not accepted him! Good heavens! Emma!—do you tell me
you have refused him?—refused Lord Osborne!"
"Yes."
"Wicked, ungrateful girl! How have you the face to stand there and
tell me such a thing? Are you mad, Emma? What bewitched you to
refuse him?"
Emma remained silent.
"Speak, wretched girl! How dared you to refuse him?"
Emma looked at her haughtily.
"I shall speak to my brother," she replied coldly.
"It is your brother who will speak to you—Minx! Do not look at me
like that! You are insufferable with your airs—and you just nothing!
Owing every stick on your back to your brother and to me!"
Jane had completely lost all self-control; and little Augusta, terrified,
clung to Emma, crying bitterly.
At this moment, Robert came into the hall.
"Here is Emma gone and refused Lord Osborne!" cried his wife.
"Do you consider the servants to be stone deaf!" he demanded
angrily. "Come with me into my study, Emma. Go with your mother,
Augusta."
Crossing the hall, he opened the door of his room for Emma to enter,
and, following her in, closed and locked it.
"What is the meaning of all this?"
Emma was too agitated to reply.
"Is it true that you have refused Lord Osborne?"
"Yes, Robert."
"And why have you refused him?" Emma strove to answer, but no
words came.
"I insist on your answering me. Why have you refused him?—you
must have some reason."
"I do not love him."
"As far as I am aware, it is not the custom for a nice girl to love a
man before he asks her. It will come in time. Listen to me, Emma. I
was anything but pleased when Lord Osborne followed you here, but
he has shown that his intentions are wholly honourable. Shortly after
our party he called on me to obtain my permission to offer himself to
you, as soon as he deemed that he might do so with reasonable
hope of success. This morning he acquainted your sister with his
design in following you. You have nothing to complain of with regard
to his conduct; he is a handsome man; and his position is far above
that you have any right to expect."
Emma remained silent, with her eyes on the ground and her cheeks
burning.
"I stand to you in the light of a father," continued Robert; "I have a
right to your obedience; and if you have any natural feelings you will
be glad to make me some return for all I have done for you—and I
am ready to do much more—by showing some willingness to comply
with what I judge to be best for you. I am not saying that I might
not have preferred that you had married a man in a simpler rank;
but as you are so difficult to suit, I could not run the risk of
dismissing him. Our aunt was no friend to you, breeding you up in a
different way to us all, making you discontented; and you should be
grateful to Lord Osborne for overlooking so much and being willing
to marry you. Promise me, Emma, that there will be no more
nonsense, if he should be so good as to forgive you for the insult
you have done him, and should come forward again."
"I cannot promise. I can never marry him."
"You can, and will marry him! Obstinate girl! What are you aiming
at? Would you prefer to attract the attentions of a royal prince?"
Robert had no sooner uttered these words than he would gladly
have recalled them—shrinking from the flash of his sister's eyes. The
next moment she had swept past him, unlocked the door, and was
gone.
Half-an-hour later she had left the house, and was on her way to
Sam at Guildford.
CHAPTER XVI
Early in January Mr. Howard returned from Spain. Had he been able
to follow his own inclinations, he would have gone straight to
Cumberland in order to look after his property, and confer with his
agent on some matters of importance; but he received such an
urgent summons from Lady Osborne that he did not like to disregard
it, and went down into Surrey.
As he entered the beautiful drawing-room of the Castle, where
everything was so familiar to him, and Lady Osborne, so entirely in
keeping with her surroundings, came forward to greet him, with a
slight flush upon her face, he could not but feel how good it was to
be once more at home.
They sat together by the wide hearth, and it seemed to him that in
the soft light of the candles she might well pass for ten years less
than her age, but as a matter of fact a stranger might well have
taken her for but little older than himself; in her beauty there was
something so soft and fair.
They had been chatting of one thing and another—principally of
Lady Edward Sothern, and the wedding—when suddenly it occurred
to him that he had not enquired for Lord Osborne, and, to his
amazement, learned that he was in Paris.
"Upon my word I do not understand him," he said, rising to his feet,
and leaning against the mantelpiece. "When we were in Italy he was
for ever playing the rôle of lonely exile, and pining for his native
land!"
He looked down at Lady Osborne, and she coloured.
"I was particularly anxious to speak to you about him," she replied.
"It is on account of his disappointment with Miss Watson. She has
definitely refused him."
"But what could have induced him to ask her when she is the
betrothed of another?"
"It was all a mistake—Mr. Musgrave confesses to having been
misinformed. She continues to live with her brother and sister at
Croydon—vulgar impossible people!—though Osborne insists that
they have a child who is a perfect little lady!—I cannot understand
these Watsons!"
On the plea of his disordered dress, Mr. Howard soon after retired,
but, as he crossed the room it was as though something of its
beauty had faded. It no longer held the same spell for him.
Something of disquiet had wakened in him. An instinct, not unakin to
a sense of shrinking, had possessed him—almost as though there
were a pitfall at his feet.
As he entered his old apartment, he was again conscious of
uneasiness. It had been freshly decorated, and re-furnished, and
there was an air of luxury which somehow repelled him, giving him a
feeling of oppression. He went over to the casement, and throwing it
wide open, regardless of frost and snow, looked out into the quiet
night, with its myriad of stars.

On the following day he set out to call on some old parishioners, and
had not gone very far on his way when he encountered Tom
Musgrave riding along.
"If ever I met such a fellow as you are, Howard! We all thought
you'd been eaten by cannibals!"
"Sorry to disappoint you!—but there are no cannibals in Spain!"
"Well, crocodiles!—it's all one!—and here's Osborne gone off to
Paris, clean out of his wits over Miss Watson!"
"How came you to make such a mistake with regard to Miss
Watson?"
"Faith! I don't know that there was any mistake! Her people are wild
with her for not having Osborne—but there seems to be some other
fellow in the background—someone she had met at her aunt's—and
she seems fully determined to have her own way. She has,
absolutely, left them at Croydon, and gone to stay with her younger
brother, where there will be nobody to look after her from morning
to night!"
This story unfortunately received confirmation during the morning;
and on the following day, when he rode over to the Rectory to see
Purvis, it received a still more disquieting aspect. Emma had been
seen in the company of a Captain Conway at A——, a man who was
said to be highly connected, though of this there was no certain
proof—but who, on the other hand, was well known to be a
profligate. Heavy at heart he returned to the Castle.
As he sat with Lady Osborne over the fire that night, she told him
more of her history than ever he had previously known.
He had always deplored the inferiority of her son and daughter to
their mother, but hitherto it had never occurred to him that she had
been conscious of it herself.
"I have known but little happiness in my life," she said. "My father,
Lord Foulke, was a gambler; and, in view of the increasing difficulty
of living, my mother believed it to be her duty to marry off all her
daughters as soon as they came out. I was the third of five girls, and
married when scarcely sixteen—no more than a child. I could not
endure Lord Osborne—my every instinct revolted against him—but
though I implored my father and mother, with tears, to spare me,
they would not listen to me. No one may know the misery of my
married life. When I was about twenty-three, however, my husband
died, leaving me with two young children—the boy so backward that
I believed him for a time to be deficient; but as I spared no effort to
develop him he gradually improved. Not long afterwards my father
died from an accident. The shock brought a stroke on my mother,
depriving her of the power of speech, which she never afterwards
recovered, though she lingered on for several years. My brother,
despite the remonstrances of the doctor, insisted on her removal to
the Dower House, and short as was the drive, she never recovered
from it; so that I dared not attempt to bring her here. As it was
seldom possible to leave her, I could see but little of my children, for
as the Dower House was small, and indifferently built, she could not
endure their noise. But never had I loved her so well. Qualities, that
I had never before discerned in her, now showed themselves, and
we were drawn together as we never had been before. At her death
I returned home, to find my daughter almost a stranger to me. Julia
was now fourteen, and her pretty manners, which I had believed to
be the expression of her affection for me, had merely served as a
mask to her serious defects of character. Perhaps unjustly, I
dismissed her governess, believing her to be blamed, and
endeavoured myself to correct them, but I had come too late, and it
only served to estrange her the further. Osborne, on the other hand,
has always held for me the simple affection of his childhood, and his
faults are rather of a negative than of a positive character, but he
cares for little beyond hunting and fishing—we have almost nothing
in common. Until you came, Arthur, I had scarcely known what it
was to have a companion."
There was a slight falter in her voice as she uttered the last words,
and she looked at her visitor wistfully.
His eyes, half veiled by their lashes, were fixed on the glowing
embers, and he remained silent. Once again Emma's soft hand
trembled in his own, and he was conscious of the beating of her
heart. Why had he not taken her into his arms, then and there, to
shelter in his breast for ever?
"Arthur, you are not listening to me!"
There was a note of reproach in the gentle voice at his side.
"I assure you, Lady Osborne, that I am deeply concerned and
distressed to hear of all that you have suffered. Perhaps in view of
my office it is scarcely orthodox for me to say how very unfair it has
all seemed—but from the point of view of a simple human being, it
is impossible to think otherwise."
Nothing could have been kinder than the tone in which he
pronounced these words; but that she had expected something
altogether different was quite evident by the expression of
disappointment which overspread her countenance, as she shrank
into the shadow.
After a moment's silence he continued:
"The want of sympathy between parents and children is only too
common, but there must have been a total absence of all natural
feeling on the part of your brother, with regard to Lady Foulke, when
he could act in such a manner towards her. The counterpart of it,
however, I witnessed at the bedside of my cousin. His son, as you
know, broke his neck in the hunting field, as his father lay dying. I
was deputed to tell him, and did so in fear and trembling as to the
possible effect it might have on him, but he just looked round at me
and said: 'And a good thing, too!' Although I had been aware that
the relations between them were very unfortunate, I had not
believed it possible that there could be such an estrangement
between father and son."
After a pause Mr. Howard then announced that he had written to his
agent to expect him on the following Saturday.
"Oh, surely not!" exclaimed his hostess, leaning forward in
expostulation. "Cumberland will be quite intolerable in this weather—
I have heard that the cold there is beyond everything!"
"I have yet to learn that I am in a galloping consumption. I assure
you there is no country more delightful and wonderful than
Cumberland in the grasp of winter!"
"I am well aware a Northman will swear anything with respect to his
country!"
"Madam! I protest!"
"Oh, protest away! you are all of you alike! I had hoped that you
might have been prevailed upon to remain with us until Easter—in
which case Osborne would have come back at once."
"Do not you think he had much better remain where he is? In the
gay world of Paris he will have everything to distract him, and may
possibly find someone to replace Miss Watson?"
"I do not think so."
"Surely you do not believe that Osborne will remain inconsolable for
ever?"
There was a gleam of humour in his dark eyes as he turned them
towards her. In all his intimate knowledge of his former pupil, it had
certainly never occurred to him that he possessed a heart of untold
depths!
"No. What I believe is, that he will revert to his former indifference
towards women, and never marry at all."
"That would be very much to be deplored."
"I am not so sure of that. He is scarcely fitted to attract a superior
mind, and you could not expect me to welcome an inferior one, or to
view, without pain, an unwilling bride forced into his arms."
A day or two later Lady Osborne stood beneath the portico, to wish
her guest "God-speed."
"Remember I shall be counting on you for an invitation!" she said,
smiling.
He bowed low.
"I shall have to secure a fair chatelaine, madam, in order to receive
you worthily!"
How little did he realize that his idle words were as a naked sword in
her breast.
CHAPTER XVII
Sam was walking along the High Street of Guildford just as the
coach drove up to the stage; and, for the moment, thinking less of
anything in the world than of Emma, when, to his amazement, she
suddenly appeared on the platform. Hastening forward, he lifted her
down; but seeing she could scarcely maintain her composure,
forbore to question her, and, drawing her hand within his arm, he
led her home.
He now lived entirely with Mr. Curtis at his residence, in a quiet
suburban road, not far off: a large, red-brick house, standing in its
own grounds, and furnished with all the comfort and suitability of
wealth and refinement. As soon as they were seated by a
comfortable fire in the library, Emma, in a few words, informed her
brother of all that had happened. He was much moved by the
recital, but deeply gratified that she had come to him at once—
indeed his satisfaction at having her would have been without
bounds, had it not been for his indignation at the conduct of Robert
and Jane, and the shock he had sustained at finding Emma travelling
by herself.
Presently Mr. Curtis, who had been out, returned to the house, and
entered the room. Sam at once introduced his sister, and while
sparing her feelings as much as possible, made him acquainted with
a sufficient account of what had occurred, to let him see that it was
impossible for Emma to return to Croydon. He then announced his
intention of at once seeking for suitable lodgings for his sister and
himself, but Mr. Curtis steadily refused to countenance such an
arrangement, insisting that as he already regarded Sam as a son, he
had some justification in venturing to hope that Miss Emma might
come to look on him as her father, and in the meantime his house
was as truly at her service. Emma thanked him charmingly, but
begged for permission to look for a situation, as governess, or
companion. On perceiving, however, the mortification she was
occasioning, both to Sam and Mr. Curtis, she was soon obliged to
give way.
Before very long her box was forwarded from Croydon, and both
Robert and Jane wrote more suitably than might have been
expected, expressing considerable regret that she had left them.
Emma was now more at ease than she had been since her quiet
time with Elizabeth, although she daily missed little Augusta; but her
health had been injured by all she had gone through. Her cheek,
once rounded with perfect health, was now thin and worn, and to
Sam's dismay she did not appear to be regaining her vitality as the
weeks went by. In view of her half-confession to him, he feared she
was suffering from a secret sorrow, and he and Mr. Curtis spared no
effort to restore her.
Towards the end of February Elizabeth's marriage was arranged, and
Mrs. John Purvis, with whom she had been residing, and from whose
house the wedding was to take place, kindly invited the whole
family, including Augusta. Emma's embarrassment at meeting Robert
and Jane was considerably lessened by this arrangement, and she
and the child were inseparable during the few days they spent
together. Penelope and Margaret had obtained leave to be present,
and both appeared improved by having been provided with
occupation, other than hunting for husbands. Mary Edwards had also
been invited, and Emma was now able to satisfy herself that she was
not wholly indifferent to Sam.
Elizabeth looked very sweet and handsome in her white bonnet and
shawl, and the bridegroom distinguished himself not a little by
forgetting neither cheque nor ring.
The sisters had been truly happy to have met together again, and
their parting was much less sorrowful than before, both bride and
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookgate.com

You might also like