SlideShare a Scribd company logo
Exam Ref 70485 Advanced Windows Store App
Development Using C Roberto Brunetti download
https://ebookbell.com/product/exam-ref-70485-advanced-windows-
store-app-development-using-c-roberto-brunetti-4428712
Explore and download more ebooks at ebookbell.com
Here are some recommended products that we believe you will be
interested in. You can click the link to download.
Exam Ref 70741 Networking With Windows Server 2016 Andrew Warren
https://ebookbell.com/product/exam-ref-70741-networking-with-windows-
server-2016-andrew-warren-46508894
Exam Ref 70533 Implementing Microsoft Azure Infrastructure Solutions
Michael Washam Rick Rainey Dan Patrick Steve Ross
https://ebookbell.com/product/exam-ref-70533-implementing-microsoft-
azure-infrastructure-solutions-michael-washam-rick-rainey-dan-patrick-
steve-ross-50200546
Exam Ref 70533 Implementing Microsoft Azure Infrastructure Solutions
Washam
https://ebookbell.com/product/exam-ref-70533-implementing-microsoft-
azure-infrastructure-solutions-washam-22029870
Exam Ref 70532 Developing Microsoft Azure Solutions Tejada
Zoinerbustamante
https://ebookbell.com/product/exam-ref-70532-developing-microsoft-
azure-solutions-tejada-zoinerbustamante-22066954
Exam Ref 70740 Installation Storage And Compute With Windows Server
2016 Kellington
https://ebookbell.com/product/exam-ref-70740-installation-storage-and-
compute-with-windows-server-2016-kellington-22066956
Exam Ref 70765 Provisioning Sql Databases Joseph Dantoni
https://ebookbell.com/product/exam-ref-70765-provisioning-sql-
databases-joseph-dantoni-22066962
Exam Ref 70345 Designing And Deploying Microsoft Exchange Server 2016
Paul Cunningham Brian Svidergol
https://ebookbell.com/product/exam-ref-70345-designing-and-deploying-
microsoft-exchange-server-2016-paul-cunningham-brian-
svidergol-33325406
Exam Ref 70484 Essentials Of Developing Windows Store Apps Using C
Indrajit Chakrabarty
https://ebookbell.com/product/exam-ref-70484-essentials-of-developing-
windows-store-apps-using-c-indrajit-chakrabarty-37206148
Exam Ref 70762 Developing Sql Databases Louis Davidson Stacia Varga
https://ebookbell.com/product/exam-ref-70762-developing-sql-databases-
louis-davidson-stacia-varga-38623980
Exam Ref 70485 Advanced Windows Store App Development Using C Roberto Brunetti
Exam Ref 70485 Advanced Windows Store App Development Using C Roberto Brunetti
Exam Ref 70485 Advanced Windows Store App Development Using C Roberto Brunetti
Exam Ref 70-485:
Advanced Windows Store
App Development
Using C#
Roberto Brunetti
Vanni Boncinelli
Published with the authorization of Microsoft Corporation by:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, California 95472
Copyright © 2013 by Roberto Brunetti and Vanni Boncinelli
All rights reserved. No part of the contents of this book may be reproduced
or transmitted in any form or by any means without the written permission of
the publisher.
ISBN: 978-0-7356-7686-2
1 2 3 4 5 6 7 8 9 QG 8 7 6 5 4 3
Printed and bound in the United States of America.
Microsoft Press books are available through booksellers and distributors
worldwide. If you need support related to this book, email Microsoft Press
Book Support at mspinput@microsoft.com. Please tell us what you think of
this book at http://www.microsoft.com/learning/booksurvey.
Microsoft and the trademarks listed at http://www.microsoft.com/about/legal/
en/us/IntellectualProperty/Trademarks/EN-US.aspx are trademarks of the
Microsoft group of companies. All other marks are property of their respec-
tive owners.
The example companies, organizations, products, domain names, email ad-
dresses, logos, people, places, and events depicted herein are fictitious. No
association with any real company, organization, product, domain name,
email address, logo, person, place, or event is intended or should be inferred.
This book expresses the author’s views and opinions. The information con-
tained in this book is provided without any express, statutory, or implied
warranties. Neither the authors, O’Reilly Media, Inc., Microsoft Corporation,
nor its resellers, or distributors will be held liable for any damages caused or
alleged to be caused either directly or indirectly by this book.
Acquisitions Editor: Jeff Riley
Developmental Editor: Kim Lindros
Production Editor: Kristen Brown
Editorial Production: Box Twelve Communications
Technical Reviewer: Luca Regnicoli
Copyeditor: Nancy Sixsmith
Indexer: Angie Martin
Cover Design: Twist Creative • Seattle
Cover Composition: Ellie Volckhausen
Illustrator: Rebecca Demarest
This book is dedicated to my parents.
— Roberto Brunetti
This book is dedicated to my family.
— Vanni Boncinelli
Exam Ref 70485 Advanced Windows Store App Development Using C Roberto Brunetti
Contents at a glance
Introduction xv
Chapter 1 Develop Windows Store apps 1
Chapter 2 Discover and interact with devices 57
Chapter 3 Program user interaction 131
Chapter 4 Enhance the user interface 193
Chapter 5 Manage data and security 275
Chapter 6 Prepare for a solution deployment 335
Index 415
About the authors 443
Exam Ref 70485 Advanced Windows Store App Development Using C Roberto Brunetti
vii
What do you think of this book? We want to hear from you!
Microsoft is interested in hearing your feedback so we can continually improve our
books and learning resources for you. To participate in a brief online survey, please visit:
www.microsoft.com/learning/booksurvey/
Contents
Introduction xv
Microsoft certifications xv
Acknowledgments xv
Errata & book support xvi
We want to hear from you xvi
Stay in touch xvi
Chapter 1 Develop Windows Store apps 1
Objective 1.1: Create background tasks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  1
Creating a background task 2
Declaring background task usage 5
Enumerating registered tasks 7
Using deferrals with tasks 7
Objective summary 8
Objective review 8
Objective 1.2: Consume background tasks . . . . . . . . . . . . . . . . . . . . . . . . . . .  9
Understanding task triggers and conditions 9
Progressing through and completing background tasks 11
Understanding task constraints 14
Cancelling a task 15
Updating a background task 18
Debugging tasks 19
Understanding task usage 21
Transferring data in the background 22
Keeping communication channels open 28
Objective review 37
viii Contents
Objective 1.3: Create and consume WinMD components. . . . . . . . . . . . . .  38
Understanding the Windows Runtime and WinMD 38
Consuming a native WinMD library 40
Creating a WinMD library 46
Objective summary 50
Objective review 50
Chapter summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  51
Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  52
Chapter 2 Discover and interact with devices 57
Objective 2.1: Capture media with the camera and microphone. . . . . . . . 57
Using CameraCaptureUI to capture pictures or video 58
Using MediaCapture to capture pictures, video, or audio 68
Objective summary 79
Objective review 80
Objective 2.2: Get data from sensors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  80
Understanding sensors and location data in the
Windows Runtime 81
Accessing sensors from a Windows Store app 81
Determining the user’s location 99
Objective summary 108
Objective review 108
Objective 2.3: Enumerate and discover device capabilities. . . . . . . . . . . .  109
Enumerating devices 110
Using the DeviceWatcher class to be notified of changes
to the device collection 117
Enumerating Plug and Play (PnP) devices 122
Objective summary 124
Objective review 124
Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  125
Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
ix
Contents
Chapter 3 Program user interaction 131
Objective 3.1: Implement printing by using contracts and charms. . . . .  131
Registering a Windows Store app for the Print contract 132
Handling PrintTask events 137
Adding the user interface 138
Creating a custom print template 140
Understanding the print task options 142
Paginating and previewing the document 144
Choosing options to display in the preview window 148
Reacting to print option changes 149
Adding custom print options 152
Implementing in-app printing 153
Objective summary 154
Objective review 154
Objective 3.2: Implement Play To by using contracts and charms . . . . .  155
Introducing the Play To contract 156
Testing sample code using Windows Media Player on a
different machine 159
Implementing a Play To source application 161
Registering your app as a Play To receiver 167
Objective summary 174
Objective review 175
Objective 3.3: Notify users by using Windows Push
Notification Service (WNS). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  176
Requesting and creating a notification channel 176
Sending a notification to the client 178
Objective summary 186
Objective review 187
Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  187
Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
x Contents
Chapter 4 Enhance the user interface 193
Objective 4.1: Design for and implement UI responsiveness. . . . . . . . . .  193
Understanding .NET asynchronous patterns 194
Writing methods using async techniques 202
Implementing asynchronous methods 204
Waiting for an event in an asynchronous way 207
Implementing asynchronous calls 208
Cancelling asynchronous operations 209
Cancelling an operation in asynchronous calls 210
Tracking operation progress 211
Tracking progress in asynchronous operations 212
Synchronizing multiple asynchronous calls 215
Waiting for multiple asynchronous calls executed in parallel 217
Choosing the right SynchronizationContext in libraries 218
Objective summary 220
Objective review 220
Objective 4.2: Create animations and transitions. . . . . . . . . . . . . . . . . . . .  221
Creating and customizing storyboarded animations 222
Exploring dependent animations vs. independent animations 225
Creating key-frame animations 228
Using interpolations and easing functions in animations 229
Using discrete animations 232
Applying animations from the animation library 233
Objective summary 238
Objective review 238
Objective 4.3: Create custom controls. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Adding a custom control to your Windows Store app 239
Creating your own dependency properties for
a custom control 243
Reacting to changes in the visual state of the custom control 246
Objective summary 251
Objective review 251
xi
Contents
Objective 4.4: Design Windows Store apps for globalization
and localization. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  252
Planning for globalization 252
Localizing your app 256
Localizing your manifest 265
Using the Multilingual App Toolkit 265
Objective summary 267
Objective review 267
Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  269
Chapter 5 Manage data and security 275
Objective 5.1: Design and implement data caching. . . . . . . . . . . . . . . . . .  275
Understanding application and user data 275
Caching application data 276
Understanding Microsoft rules for using roaming
profiles with Windows Store apps 286
Caching user data 287
Objective summary 290
Objective review 290
Objective 5.2: Save and retrieve files from the file system. . . . . . . . . . . .  291
Using file pickers to save and retrieve files 291
Accessing files and data programmatically 298
Working with folders, files, and streams 300
Setting file extensions and associations 301
Compressing files to save space 304
Objective summary 305
Objective review 306
Objective 5.3: Secure app data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Introducing the Windows.Security.Cryptography namespaces 307
Using hash algorithms 308
Generating random numbers and data 311
Encrypting messages with MAC algorithms 313
Using digital signatures 316
xii Contents
Enrolling and requesting certificates 319
Protecting your data with the DataProtectionProvider class 325
Objective summary 328
Objective review 329
Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  329
Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
Chapter 6 Prepare for a solution deployment 335
Objective 6.1: Design and implement trial functionality in an app. . . . .  335
Choosing the right business model for your app 336
Exploring the licensing state of your app 338
Using custom license information 344
Purchasing an app 345
Handling errors 349
Setting up in-app purchases 350
Retrieving and validating the receipts for your purchases 356
Objective summary 358
Objective review 358
Objective 6.2: Design for error handling . . . . . . . . . . . . . . . . . . . . . . . . . . .  359
Handling exceptions in the .NET Framework 359
Catching errors and exceptions at the application level 361
Handling device capability errors 364
Handling asynchronous errors 368
Objective summary 373
Objective review 374
Objective 6.3: Design and implement a test strategy. . . . . . . . . . . . . . . . . 374
Understanding functional testing vs. unit testing 375
Implementing a test project for a Windows Store app 378
Objective summary 387
Objective review 387
xiii
Contents
Objective 6.4: Design a diagnostics and monitoring strategy. . . . . . . . . 388
Profiling a Windows Store app and collecting
performance counters 388
Tracing and logging events for Windows Store apps 398
Using Windows Store reports to improve the quality of
your app 402
Objective summary 405
Objective review 406
Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
Index 415
What do you think of this book? We want to hear from you!
Microsoft is interested in hearing your feedback so we can continually improve our
books and learning resources for you. To participate in a brief online survey, please visit:
www.microsoft.com/learning/booksurvey/
Exam Ref 70485 Advanced Windows Store App Development Using C Roberto Brunetti
xv
Introduction
The Microsoft 70-485 certification exam tests your knowledge of Windows Store application
development using C#. Readers are assumed to be Windows Store app developers with deep
knowledge of the Windows Runtime architecture, the application life cycle managed by the
system (including suspend, termination, resume, and launch), the Visual Studio 2012 project
structure, the application manifest, app deployment, and Windows Store requirements. The
reader must have also a strong background in XAML and C#.
This book covers every exam objective, but it does not cover every exam question. Only
the Microsoft exam team has access to the exam questions themselves, and Microsoft regu-
larly adds new questions to the exam, making it impossible to cover specific questions. You
should consider this book a supplement to your relevant real-world experience and other
study materials. If you encounter a topic in this book that you do not feel completely com-
fortable with, use the links you’ll find in text to find more information and take the time to
research and study the topic. Great information is available on MSDN, TechNet, and in blogs
and forums.
Microsoft certifications
Microsoft certifications distinguish you by proving your command of a broad set of skills and
experience with current Microsoft products and technologies. The exams and corresponding
certifications are developed to validate your mastery of critical competencies as you design
and develop, or implement and support, solutions with Microsoft products and technologies
both on-premise and in the cloud. Certification brings a variety of benefits to the individual
and to employers and organizations.
MORE INFO All Microsoft certifications
For information about Microsoft certifications, including a full list of available certifica-
tions, go to http://www.microsoft.com/learning/en/us/certification/cert-default.aspx.
Acknowledgments
I’d like to thank Vanni for his side-by-side work. He has shared with me all the intricacies of
writing a book with this level of detail.
— Roberto Brunetti
xvi Introduction
I’d like to thank Roberto for teaching me everything I know today about software develop-
ment, and Marika for her support and infinite patience during the writing of this book.
— Vanni Boncinelli
Roberto and Vanni want to thank all the people who made this book possible. In particu-
lar, we thank Kim Lindros, for her exceptional support throughout the editing process of this
book; Jeff Riley, for giving us this opportunity; and Russell Jones, for introducing our team to
Jeff.
Special thanks to Wouter de Kort for providing some of the content in Chapter 4.
Errata & book support
We’ve made every effort to ensure the accuracy of this book and its companion content.
Any errors that have been reported since this book was published are listed on our Microsoft
Press site at oreilly.com:
http://aka.ms/ER70-485/errata
If you find an error that is not already listed, you can report it to us through the same
page.
If you need additional support, email Microsoft Press Book Support at
mspinput@microsoft.com.
Please note that product support for Microsoft software is not offered through the ad-
dresses above.
We want to hear from you
At Microsoft Press, your satisfaction is our top priority, and your feedback our most valuable
asset. Please tell us what you think of this book at:
http://www.microsoft.com/learning/booksurvey
The survey is short, and we read every one of your comments and ideas. Thanks in ad-
vance for your input!
Stay in touch
Let’s keep the conversation going! We’re on Twitter: http://twitter.com/MicrosoftPress.
1
C H A P T E R 1
Develop Windows Store apps
In this chapter, you learn how to create background tasks and implement the appropriate
interfaces for a Windows Store app. You also find out how to consume them using timing
and system triggers, request lock screen access, and create download and upload opera-
tions using the BackgroundTransfer class. The last part of the chapter is dedicated to creat-
ing and consuming WinMD components.
Objectives in this chapter:
■
■ Objective 1.1: Create background tasks
■
■ Objective 1.2: Consume background tasks
■
■ Objective 1.3: Create and consume WinMD components
Objective 1.1: Create background tasks
Windows 8 changes the way applications run. Windows Store application life-cycle manage-
ment of the Windows Runtime (WinRT) is different from previous versions of Windows: only
one application (or two in snapped view) can run in the foreground at a time. The system
can suspend or even terminate other apps from the Windows Runtime. This behavior forces
the developer to use different techniques to implement some form of background work,
such as to download a file or perform tile updates.
This section covers how to implement a background task using the provided classes and
interfaces, and how to code a simple task.
This objective covers how to:
■
■ Create a background task
■
■ Use the Windows.ApplicationModel.Background classes
■
■ Implement the IBackgroundTask interface
2 CHAPTER 1 Develop Windows Store apps
Creating a background task
In Windows Store apps, when users work on an app in the foreground, background apps can-
not interact directly with them. In fact, due to the architecture of Microsoft Windows 8 and
because of the application life-cycle management of Windows Store apps, only the foreground
app has the focus and is in the running state; the user can choose two applications in the fore-
ground using the snapped view. All the other background apps can be suspended and even
terminated by the Windows Runtime. A suspended app cannot execute code, consume CPU
cycles or network resources, or perform disk activity such as reading or writing files.
You can define a background task that runs in the background, however, even in a
separate process from the owner app, and you can define background actions. When these
actions need to alert users about their outcomes, they can use a toast. A background task can
execute code even when the corresponding app is suspended, but it runs in an environment
that is restricted and resource-managed. Moreover, background tasks receive only a limited
amount of system resources.
You should use a background task to execute small pieces of code that require no user
interaction. You can also use a background task to communicate with other apps via instant
messaging, email, or Voice over IP (VoIP). Avoid using a background task to execute complex
business logic or calculations because the amount of system resources available to back-
ground apps is limited. Complex background workloads consume battery power as well,
reducing the overall efficiency and responsiveness of the system.
To create a background task, you have to define a class and register it with the oper-
ating system. To do this, create a Windows Metadata (WinMD) project and then create
a class in it. A background task is a public and not-inheritable class that implements the
IBackgroundTask interface defined by the Windows Runtime and is registered by using a
BackgroundTaskBuilder class instance.
MORE INFO WINMD
WinMD is covered in the section titled “Objective 1.3: Create and consume WinMD compo-
nents” later in this chapter.
The IBackgroundTask imposes the implementation of a single self-explaining method: Run.
Listing 1-1 shows the implementation of this interface in a sample class.
LISTING 1-1 Class skeleton for IBackground task interface implementation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
namespace BikeGPS
{
Objective 1.1: Create background tasks CHAPTER 1 3
public sealed class BikePositionUpdateBackgroundTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
// Update the GPS coordinates
}
}
}
You have to assign the event that will fire the task. When the event occurs, the operating
system calls the defined Run method. You can associate the event, called a trigger, via the
SystemTrigger or the MaintenanceTrigger class.
The code is straightforward. Using an instance of the BackgroundTaskBuilder class, associ-
ate the name of the task and its entry point by using the syntax namespace.class. The entry
point represents the background task class, as shown in the following code:
Sample of C# code
var taskName = "bikePositionUpdate";
var builder = new BackgroundTaskBuilder();
builder.Name = taskName;
builder.TaskEntryPoint = "BikeGPS.BikePositionUpdateBackgroundTask";
You must also create the trigger to let the system know when to start the background task:
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
The SystemTrigger class accepts two parameters in its constructor. The first parameter
of the trigger is the type of system event associated with the background task; the second,
called oneShot, tells the Windows Runtime to start the task only once or every time the event
occurs.
The complete enumeration, which is defined by the SystemTriggerType enum, is shown in
Listing 1-2.
LISTING 1-2 Types of system triggers
// Summary:
// Specifies the system events that can be used to trigger a background task.
[Version(100794368)]
public enum SystemTriggerType
{
// Summary:
// Not a valid trigger type.
Invalid = 0,
//
// Summary:
// The background task is triggered when a new SMS message is received by an
// installed mobile broadband device.
SmsReceived = 1,
//
// Summary:
// The background task is triggered when the user becomes present. An app must
// be placed on the lock screen before it can successfully register background
// tasks using this trigger type.
4 CHAPTER 1 Develop Windows Store apps
UserPresent = 2,
//
// Summary:
// The background task is triggered when the user becomes absent. An app must
// be placed on the lock screen before it can successfully register background
// tasks using this trigger type.
UserAway = 3,
//
// Summary:
// The background task is triggered when a network change occurs, such as a
// change in cost or connectivity.
NetworkStateChange = 4,
//
// Summary:
// The background task is triggered when a control channel is reset. An app must
// be placed on the lock screen before it can successfully register background
// tasks using this trigger type.
ControlChannelReset = 5,
//
// Summary:
// The background task is triggered when the Internet becomes available.
InternetAvailable = 6,
//
// Summary:
// The background task is triggered when the session is connected. An app must
// be placed on the lock screen before it can successfully register background
// tasks using this trigger type.
SessionConnected = 7,
//
// Summary:
// The background task is triggered when the system has finished updating an
// app.
ServicingComplete = 8,
//
// Summary:
// The background task is triggered when a tile is added to the lock screen.
LockScreenApplicationAdded = 9,
//
// Summary:
// The background task is triggered when a tile is removed from the lock screen.
LockScreenApplicationRemoved = 10,
//
// Summary:
// The background task is triggered when the time zone changes on the device
// (for example, when the system adjusts the clock for daylight saving time).
TimeZoneChange = 11,
//
// Summary:
// The background task is triggered when the Microsoft account connected to
// the account changes.
OnlineIdConnectedStateChange = 12,
}
You can also add conditions that are verified by the system before starting the back-
ground task. The BackgroundTaskBuilder class exposes the AddCondition method to add a
Objective 1.1: Create background tasks CHAPTER 1 5
single condition, as shown in the following code sample. You can call it multiple times to add
different conditions.
builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
The last line of code needed is the registration of the defined task:
BackgroundTaskRegistration taskRegistration = builder.Register();
Declaring background task usage
An application that registers a background task needs to declare the feature in the applica-
tion manifest as an extension, as well as the events that will trigger the task. If you forget
these steps, the registration will fail. There is no <Extensions> section in the application
manifest of the Microsoft Visual Studio standard template by default, so you need to insert it
as a child of the Application tag.
Listing 1-3 shows the application manifest for the sample task implemented by the previ-
ous code (see Listing 1-2). The <Extensions> section is highlighted in bold.
LISTING 1-3 Application manifest
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
<Identity Name="e00b2bde-0697-4e6b-876b-1d611365485f"
Publisher="CN=Roberto"
Version="1.0.0.0" />
<Properties>
<DisplayName>BikeApp</DisplayName>
<PublisherDisplayName>Roberto</PublisherDisplayName>
<Logo>AssetsStoreLogo.png</Logo>
</Properties>
<Prerequisites>
<OSMinVersion>6.2.1</OSMinVersion>
<OSMaxVersionTested>6.2.1</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="BikeApp.App">
<VisualElements
DisplayName="BikeApp"
Logo="AssetsLogo.png"
SmallLogo="AssetsSmallLogo.png"
Description="BikeApp"
6 CHAPTER 1 Develop Windows Store apps
ForegroundText="light"
BackgroundColor="#464646">
<DefaultTile ShowName="allLogos" />
<SplashScreen Image="AssetsSplashScreen.png" />
</VisualElements>
<Extensions>
<Extension Category="windows.backgroundTasks"
EntryPoint="BikeGPS.BikePositionUpdateBackgroundTask">
<BackgroundTasks>
<Task Type="systemEvent" />
</BackgroundTasks>
</Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>
You have to add as many task elements as needed by the application. For example, if the
application uses a system event and a push notification event, you must add the following
XML node to the BackgroundTasks element:
<BackgroundTasks>
<Task Type="systemEvent" />
<Task Type="pushNotification" />
</BackgroundTasks>
You can also use the Visual Studio App Manifest Designer to add (or remove) a back-
ground task declaration. Figure 1-1 shows the same declaration in the designer.
FIGURE 1-1 Background task declaration in the Visual Studio App Manifest Designer
Objective 1.1: Create background tasks CHAPTER 1 7
Enumerating registered tasks
Be sure to register the task you implement just once in your application. If you forget to check
the presence of the task, you risk registering and executing the same task many times.
To see whether a task is registered, you can iterate all the registered tasks using the
BackgroundTaskRegistration class and checking for the Value property that exposes the Name
property, as follows:
Sample of C# code
var taskName = "bikePositionUpdate";
var taskRegistered = false;
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == taskName)
{
taskRegistered = true;
break;
}
}
if (!taskRegistered)
// Register the task
Using deferrals with tasks
If the code for the Run method is asynchronous, the background task needs to use a deferral
(the same techniques of the suspend method) using the GetDeferral method, as shown in the
following code:
public async void Run(IBackgroundTaskInstance taskInstance)
{
BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();
//
// Start one (or more) async
// Use the await keyword
//
await UpdateGPSCoordinatesAsync();
_deferral.Complete();
}
After requesting the deferral, use the async/await pattern to perform the asynchronous
work and, at the end, call the Complete method on the deferral. Be sure to perform all the
work after requesting the deferral and before calling the Complete method. Otherwise, the
system thinks that your job is already done and can shut down the main thread.
8 CHAPTER 1 Develop Windows Store apps
Thought experiment
Implementing background tasks
In this thought experiment, apply what you’ve learned about this objective. You can
find answers to these questions in the “Answers” section at the end of this chapter.
Your application needs to perform some lengthy cleaning operations on temporary
data. To avoid wasting system resources during application use, you want to per-
form these operations in the background. You implement the code in a background
thread, but notice that your application sometimes does not clean all the data when
the user switches to another application.
1. Why does the application not clean the data all the time?
2. How can you solve this problem?
Objective summary
■
■ A background task can execute lightweight action invoked by the associated event.
■
■ A task needs to be registered using WinRT classes and defined in the application
manifest.
■
■ There are many system events you can use to trigger a background task.
■
■ You have to register a task just once.
■
■ You can enumerate tasks that are already registered.
Objective review
Answer the following questions to test your knowledge of the information in this objective.
You can find the answers to these questions and explanations of why each answer choice is
correct or incorrect in the “Answers” section at the end of this chapter.
1. How can an application fire a background task to respond to a network state
modification?
A. By using a time trigger that polls the network state every minute, and checks for
changes to this value
B. By using a SystemTrigger for the InternetAvailable event and checking to see
whether the network is present or not
C. By using a SystemTrigger for the NetworkStateChange event and using false as the
second constructor parameter (called oneShot)
D. By using a SystemTrigger for the NetworkStateChange event and using true as the
second constructor parameter
Objective 1.2: Consume background tasks CHAPTER 1 9
2. Which steps do you need to perform to enable a background task? (Choose all that
apply.)
A. Register the task in the Package.appxmanifest file.
B. Use the BackgroundTaskBuilder to create the task.
C. Set the trigger that will fire the task code.
D. Use a toast to show information to the user.
3. Is it possible to schedule a background task just once?
A. Yes, using a specific task.
B. No, only system tasks can run once.
C. Yes, using a parameter at trigger level.
D. No, only a time-triggered task can run once at certain time.
Objective 1.2: Consume background tasks
The Windows Runtime exposes many ways to interact with the system in a background task
and many ways to activate a task. System triggers, time triggers, and conditions can modify
the way a task is started and consumed. Moreover, a task can keep a communication channel
open to send data to or receive data from remote endpoints. An application might need to
download or upload a large resource even if the user is not using it. The application can also
request lock screen permission from the user to enhance other background capabilities.
This objective covers how to:
■
■ Use timing and system triggers
■
■ Keep communication channels open
■
■ Request lock screen access
■
■ Use the BackgroundTransfer class to finish downloads
Understanding task triggers and conditions
Many types of background tasks are available. They respond to different kinds of triggers for
any kind of application, which can be the following:
■
■ MaintenanceTrigger Raised when it is time to execute system maintenance tasks
■
■ SystemEventTrigger Raised when a specific system event occurs
10 CHAPTER 1 Develop Windows Store apps
A maintenance trigger is represented by the MaintenanceTrigger class. This class imple-
ments the IBackgroundTrigger interface, as do other triggers available in the Windows
Runtime library. The interface in this version of the Windows Runtime declares nothing, but
will be implemented in future versions of the library. To create a new instance of a trigger, you
can use the following code:
MaintenanceTrigger taskTrigger = new MaintenanceTrigger(60, true);
The first parameter is the freshnessTime expressed in minutes, and the second parameter,
called oneShot, is a Boolean indicating whether the trigger should be fired only one time or
every freshnessTime occurrence.
Whenever a system event occurs, you can check a set of conditions to determine whether
your background task should execute. When a trigger is fired, the background task does not
run until all its conditions are met, which means the code for the Run method is not executed
if a condition is not met.
All the conditions are enumerated in the SystemConditionType enum:
■
■ InternetAvailable An Internet connection must be available.
■
■ InternetNotAvailable An Internet connection must be unavailable.
■
■ SessionConnected The session must be connected.
■
■ SessionDisconnected The session must be disconnected.
■
■ UserNotPresent The user must be away.
■
■ UserPresent The user must be present.
The maintenance trigger can schedule a background task as frequently as every 15 min-
utes if the device is plugged in to an AC power source. It is not fired if the device is running
on batteries.
System triggers and maintenance triggers run for every application that registers them
(and declares them in the application manifest). In addition, an application that leverages the
lock screen–capable feature of the Windows Runtime can also register background tasks for
other events.
An application can be placed on the lock screen to show important information to the
user: The user can choose the application he or she wants on the lock screen (up to seven in
the first release of Windows 8).
You can use the following triggers to run code for an app on the lock screen:
■
■ PushNotificationTrigger Raised when a notification arrives on the Windows Push
Notifications Service channel.
■
■ TimeTrigger Raised at scheduled intervals. The app can schedule a task to run as
frequently as every 15 minutes.
■
■ ControlChannelTrigger Raised when there are incoming messages on the control
channel for apps that keep connections alive.
Objective 1.2: Consume background tasks CHAPTER 1 11
It is important to note that the user must place the application on the lock screen before
the application can use triggers. The application can ask the user to access the lock screen by
calling the RequestAccessAsync method. The system presents a dialog box to the user, asking
for her or his permission to use the lock screen.
The following triggers are usable only by lock screen–capable applications:
■
■ ControlChannelReset The control channel is reset.
■
■ SessionConnected The session is connected.
■
■ UserAway The user must be away.
■
■ UserPresent The user must be present.
In addition, when a lock screen–capable application is placed on the lock screen or re-
moved from it, the following system events are triggered:
■
■ LockScreenApplicationAdded The application is added to the lock screen.
■
■ LockScreenApplicationRemoved The application is removed from the lock.
A time-triggered task can be scheduled to run either once or periodically; this kind of task
is useful to update the application tile or badge with some kind of information. For example,
a weather app updates the temperature to show the most recent one in the application tile,
whereas a finance application refreshes the quote for the preferred stock.
The code to define a time trigger is similar to the code for a maintenance trigger:
TimeTrigger taskTrigger = new TimeTrigger(60, true);
The first parameter (freshnessTime) is expressed in minutes, and the second parameter
(oneShot) indicates whether the trigger will fire only once or at every freshnessTime occurrence.
The Windows Runtime has an internal timer that runs tasks every 15 minutes. If the
freshnessTime is set to 15 minutes and oneShot is set to false, the task will run every 15
minutes, starting between the time the task is registered and the 15 minutes ahead. If the
freshnessTime is set to 15 minutes and oneShot is set to true, the task will run 15 minutes from
the registration time.
EXAM TIP
You cannot set the freshnessTime to a value less than 15 minutes. An exception occurs if
you try to do this.
Time trigger supports all the conditions in the SystemConditionType enum presented ear-
lier in this section.
Progressing through and completing background tasks
If an application needs to know the result of the task execution, it can provide a callback for
the OnCompleted event. The callback receives the instance of the BackgroundTaskRegistration
used to register the task and the corresponding event arguments.
12 CHAPTER 1 Develop Windows Store apps
The following code creates a task and registers an event handler for the completion event:
var builder = new BackgroundTaskBuilder();
builder.Name = taskName;
builder.TaskEntryPoint = "BikeGPS.BikePositionUpdateBackgroundTask";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
BackgroundTaskRegistration taskRegistration = builder.Register();
taskRegistration.Completed += taskRegistration_Completed;
A simple event handler, receiving the BackgroundTaskRegistration as the sender, can show
something to the user as in the following code, or it can update the application tile with some
information:
void taskRegistration_Completed(BackgroundTaskRegistration sender,
BackgroundTaskCompletedEventArgs args)
{
if (sender.Name == "BikeGPS.BikePositionUpdateBackgroundTask")
{
var dialog = new MessageDialog("Task BikePositionUpdateBackgroundTask
completed.");
dialog.ShowAsync();
}
}
EXAM TIP
A background task can be executed when the application is suspended or even terminated.
The OnCompleted event callback will be fired when the application is resumed from the
operating system or the user launches it again. If the application is in the foreground, the
event callback is fired immediately.
A well-written application needs to check errors in the task execution. Because the task
is already completed, you need to see whether the result is available or whether some-
thing went wrong. To do that, the code can call the CheckResult method of the received
BackgroundTaskCompletedEventArgs. This method throws the exception that occurred during
task execution, if any; otherwise, it simply returns a void.
Listing 1-4 shows the correct way to handle an exception inside a single task.
LISTING 1-4 Completed event with exception handling
void taskRegistration_Completed(BackgroundTaskRegistration sender,
BackgroundTaskCompletedEventArgs args)
{
if (sender.Name == "BikeGPS.BikePositionUpdateBackgroundTask")
{
try
Objective 1.2: Consume background tasks CHAPTER 1 13
{
args.CheckResult();
var dialog = new MessageDialog(
"Task BikePositionUpdateBackgroundTask completed successfully");
dialog.ShowAsync();
}
catch (Exception ex)
{
var dialog = new MessageDialog(
"Task BikePositionUpdateBackgroundTask Errors " + ex.Message);
dialog.ShowAsync();
}
}
}
Right after the check for the task name, exposed by the Name property of the Back-
groundTaskRegistration received in the event handler parameter, use a try/catch block to
intercept the exception fired by the CheckResult method, if any. In the sample presented in
Listing 1-4, we simply create a dialog box to show the correct completion or the exception
thrown by the background task execution.
Another useful event a background task exposes is the OnProgress event that, as the name
implies, can track the progress of an activity. The event handler can update the user interface
that is displayed when the application is resumed, or update the tile or the badge with the
progress (such as the percent completed) of the job.
The code in Listing 1-5 is an example of a progress event handler that updates application
titles manually:
LISTING 1-5 Sample progress event handler that updates the application tile
void taskRegistration_Progress(BackgroundTaskRegistration sender,
BackgroundTaskProgressEventArgs args)
{
string tileXmlString = "<tile>"
+ "<visual>"
+ "<binding template='TileWideText03'>"
+ "<text id='1'>" + args.Progress.ToString() + "</text>"
+ "</binding>"
+ "<binding template='TileSquareText04'>"
+ "<text id='1'>" + args.Progress.ToString() + "</text>"
+ "</binding>"
+ "</visual>"
+ "</tile>";
var tileXml = new Windows.Data.Xml.Dom.XmlDocument();
tileXml.LoadXml(tileXmlString);
var tile = new Windows.UI.Notifications.TileNotification(tileXml);
Windows.UI.Notifications.TileUpdateManager.CreateTileUpdaterForApplication()
.Update(tile);
}
14 CHAPTER 1 Develop Windows Store apps
The code in Listing 1-5 builds the XML document using the provided template and creates
a TileNotification with a single value representing the process percentage. Then the code uses
the CreateTileUpdaterForApplication method of the TileUpdateManager class to update the
live tile.
The progress value can be assigned in the Run method using the Progress property of the
IBackgroundTaskInstance instance that represents the task. This instance is received directly as
the parameter of the Run method.
The following code shows a simple example of progress assignment:
public sealed class BikePositionUpdateBackgroundTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
// Update the GPS coordinates
// First operation
taskInstance.Progress = 10;
// Second operation
taskInstance.Progress = 20;
/// ....
}
}
Understanding task constraints
As stated, background tasks have to be lightweight so they can provide the best user experi-
ence with foreground apps and battery life. The runtime enforces this behavior by applying
resource constraints to the task:
■
■ CPU for application not on the lock screen The CPU is limited to 1 second. A task
can run every 2 hours at a minimum. For application on the lock screen, the system will
execute a task for 2 seconds with a 15-minute maximum interval.
■
■ Network access When running on batteries, tasks have network usage limits cal-
culated based on the amount of energy used by the network card. This number can
be very different from device to device based on their hardware. For example, with a
throughput of 10 megabits per second (Mbps), an app on the lock screen can consume
about 450 megabytes (MB) per day, whereas an app that is not on the lock screen can
consume about 75 MB per day.
MORE INFO TASK CONSTRAINTS
Refer to the MSDN documentation at http://msdn.microsoft.com/en-us/library/win-
dows/apps/xaml/hh977056.aspx for updated information on background task resource
constraints.
Objective 1.2: Consume background tasks CHAPTER 1 15
To prevent resource quotas from interfering with real-time communication apps, tasks
using ControlChannelTrigger and PushNotificationTrigger receive a guaranteed resource
quota (CPU/network) for every running task. The resource quotas and network data usage
constraints remain constant for these background tasks rather than varying according to the
power usage of the network interface.
Because the system handles constraints automatically, your app does not have to request
resource quotas for ControlChannelTrigger and PushNotificationTrigger background tasks. The
Windows Runtime treats these tasks as “critical” background tasks.
If a task exceeds these quotas, it is suspended by the runtime. You can check for suspen-
sion by inspecting the SuspendedCount property of the task instance in the Run method,
choosing to stop or abort the task if the counter is too high. The following code illustrates
how to check for suspension:
public sealed class BikePositionUpdateBackgroundTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
// Update the GPS coordinates
if (taskInstance.SuspendedCount > 5)
return;
}
}
Cancelling a task
When a task is executing, it cannot be stopped unless the task recognizes a cancellation re-
quest. A task can also report cancellation to the application using the persistent storage.
The Run method has to check for cancellation requests. The easiest way is to declare a
Boolean variable in the class and set it to true if the system has cancelled the task. This vari-
able will be set to true in the OnCanceled event handler and checked during the execution of
the Run method to exit it.
Listing 1-6 shows the simplest complete class to check for cancellation.
LISTING 1-6 Task cancellation check
public sealed class BikePositionUpdateBackgroundTask : IBackgroundTask
{
volatile bool _cancelRequested = false;
public void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);
// Update the GPS coordinates
// First operation
taskInstance.Progress = 10;
16 CHAPTER 1 Develop Windows Store apps
if (_cancelRequested == true)
return;
// Second operation
taskInstance.Progress = 20;
/// ....
}
private void OnCanceled(IBackgroundTaskInstance sender,
BackgroundTaskCancellationReason reason)
{
// you can use sender.Task.Name to identity the task
_cancelRequested = true;
}
}
In the Run method, the first line of code sets the event handler for the Canceled event to
the OnCanceled method. Then it does its job setting the progress and testing the value of the
variable to stop working (return or break, in case of a loop). The OnCanceled method sets the
_cancelRequested variable to true. To recap, the system will call the Canceled event handler
(OnCanceled) during a cancellation. The code sets the variable tested in the Run method to
stop working on the task.
If the task wants to communicate some data to the application, it can use local persistent
storage as a place to store some data the application can interpret. For example, the Run
method can save the status in a LocalSettings key to let the application know if the task has
been successfully completed or cancelled. The application can then check this information in
the Completed event for the task.
Listing 1-7 shows the revised Run method.
LISTING 1-7 Task cancellation using local settings to communicate information to the app
public void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);
// Update the GPS coordinates
// First operation
taskInstance.Progress = 10;
if (_cancelRequested == true)
{
ApplicationData.Current.LocalSettings.Values["status"] = "canceled";
return;
}
// Second operation
taskInstance.Progress = 20;
Objective 1.2: Consume background tasks CHAPTER 1 17
/// ....
///
ApplicationData.Current.LocalSettings.Values["status"] = "completed";
}
Before “stopping” the code in the Run method, the code sets the status value in the
LocalSettings; that is, the persistent storage dedicated to the application, to canceled. If the
task completes its work, the value will be completed.
The code in Listing 1-8 inspects the LocalSettings value to determine the task outcome.
This is a revised version of the taskRegistration_Completed event handler used in a previous
sample.
LISTING 1-8 Task completed event handler with task outcome check
void taskRegistration_Completed(BackgroundTaskRegistration sender,
BackgroundTaskCompletedEventArgs args)
{
if (sender.Name == "BikeGPS.BikePositionUpdateBackgroundTask")
{
try
{
args.CheckResult();
var status = ApplicationData.Current.LocalSettings.Values["status"];
MessageDialog dialog;
if(status == "canceled")
dialog = new MessageDialog(
"Task BikePositionUpdateBackgroundTask canceled");
else
dialog = new MessageDialog(
"Task BikePositionUpdateBackgroundTask completed");
dialog.ShowAsync();
}
catch (Exception ex)
{
var dialog = new MessageDialog(
"Task BikePositionUpdateBackgroundTask Errors " + ex.Message);
dialog.ShowAsync();
}
}
}
The registered background task persists in the local system and is independent from the
application version.
18 CHAPTER 1 Develop Windows Store apps
Updating a background task
Tasks “survive” application updates. If a newer version of the application needs to update a
task or modify its behavior, it can register the background task with the ServicingComplete
trigger; this way the app is notified when the application is updated and unregisters tasks that
are no longer valid.
Listing 1-9 shows a task that unregisters the previous version and registers the new one.
LISTING 1-9 Using the ServicingComplete task to update a previous version of a task
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using Windows.Storage;
namespace BikeGPS
{
public sealed class ServicingCompleteTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
// Look for Task v1
var task = FindTask("BikeGPS.BikePositionUpdateBackgroundTask");
if (task != null)
{
task.Unregister(true);
}
var builder = new BackgroundTaskBuilder();
builder.Name = task.Name;
builder.TaskEntryPoint = "BikeGPS.BikePositionUpdateBackgroundTask";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange,
false));
builder.AddCondition(new
SystemCondition(SystemConditionType.InternetAvailable));
BackgroundTaskRegistration taskRegistration = builder.Register();
}
Objective 1.2: Consume background tasks CHAPTER 1 19
public static BackgroundTaskRegistration FindTask(string taskName)
{
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == taskName)
{
return (BackgroundTaskRegistration)(task.Value);
}
}
return null;
}
}
}
The parameter of the Unregister method set to true forces task cancellation, if implemented,
for the background task. The FindTask method is simply a helper you can use throughout the
code to find a task by name in the list of already registered tasks and return it to the caller.
The last thing to do is use a ServicingComplete task in the application code to register this
“system” task as other tasks using the ServicingComplete system trigger type:
SystemTrigger servicingCompleteTrigger =
new SystemTrigger(SystemTriggerType.ServicingComplete, false);
Debugging tasks
Debugging a background task can be a challenging job if you try to use a manual tracing
method.
A timer or a maintenance-triggered task can be executed in the next 15 minutes based on
the internal interval, so debugging manually is not so effective. To ease this job, the Visual
Studio background task integrated debugger simplifies the task activation.
Make sure that the Windows Store application references the background task project
and the latter is configured as WinMD File. In addition, the project has to declare the back-
ground task in the application manifest. Figure 1-2 shows the complete solution with the
BikeBackgroundTask project referenced by the main application, and the project property
showing the output type set to Windows Runtime Component (also referred to as the WinMD
library or file).
20 CHAPTER 1 Develop Windows Store apps
FIGURE 1-2 Solution structure and output type for a background task
Place a breakpoint in the Run method or use the Debug class to write some values in the
output window. Start the project at least one time to register the task in the system and then
use the Debug Location toolbar in Visual Studio to activate the background task. The toolbar
can show only registered tasks waiting for the trigger. The toolbar can be activated using the
View command on the Toolbars menu.
Figure 1-3 shows the background registration code and the Debug Location toolbar.
FIGURE 1-3 Visual Studio “hidden” Debug Location toolbar to start tasks
Objective 1.2: Consume background tasks CHAPTER 1 21
Figure 1-4 shows the debugger inside the Run method.
FIGURE 1-4 Debugging tasks activated directly from Visual Studio
Understanding task usage
Every application has to pass the verification process during application submission to the
Windows Store. Be sure to double-check the code for background tasks using the following
points as guidance:
■
■ Do not exceed the CPU and network quotas in your background tasks. Tasks have to
be lightweight to save battery power and provide a better user experience for the ap-
plication in the foreground.
22 CHAPTER 1 Develop Windows Store apps
■
■ The application should get the list of registered background tasks, register for progress
and completion handlers, and handle these events in the correct manner. The classes
should also report progress, cancellation, and completion.
■
■ If the Run method uses asynchronous code, make sure the code uses deferrals to avoid
premature termination of the method before completion. Without a deferral, the
Windows Runtime thinks that your code has finished its work and can terminate the
thread. Request a deferral, use the async/await pattern to complete the asynchronous
call, and close the deferral after the await keyword.
■
■ Declare each background task and every trigger associated with it in the application
manifest. Otherwise, the app cannot register the task at runtime.
■
■ Use the ServicingComplete trigger to prepare your application for updating.
■
■ If you use the lock screen–capable feature, remember that only seven apps can be
placed on the lock screen, and the user can choose the application she wants on it at
any time. Furthermore, only one app can have a wide tile. The application can provide
a good user experience by requesting lock screen access using the RequestAccessAsync
method. Be sure the application can work without permission to use the lock screen
because the user can deny access to it or remove the permission later.
■
■ Use tiles and badges to provide visual clues to the user and use the notification mecha-
nism in the task to notify third parties. Do not use any other UI elements in the run
method.
■
■ Use persistent storage as ApplicationData to share data between the background task
and the application. Never rely on user interaction in the task.
■
■ Write background tasks that are short-lived.
Transferring data in the background
Some applications need to download or upload a resource from the web. Because of the ap-
plication life-cycle management of the Windows Runtime, if you begin to download a file and
then the user switches to another application, the first app can be suspended; the file cannot
be downloaded during suspension because the system gives no thread and no I/O slot to a
suspended app. If the user switches back to the application again, the download operation
can continue but will take more time to be completed. Moreover, if the system needs resourc-
es, it can terminate the application. The download is then terminated together with the app.
The BackgroundTransfer namespace provides classes to avoid these problems. It can be
used to enhance the application with file upload and download features that run in the back-
ground during suspension. It supports HTTP and HTTPS for download and upload operations,
and File Transfer Protocol (FTP) for download-only operations. This class is aimed at large file
uploads and downloads.
Objective 1.2: Consume background tasks CHAPTER 1 23
The process started by this class runs separately from the Windows Store app and can
be used to work with resources such as files, music, large images, and videos. During the
operation, if the runtime chooses to put the application in the suspended state, the capability
provided by the Background Transfer APIs continues to work in the background.
NOTE BACKGROUND TRANSFER API
Background Transfer APIs work for small resources (a few kilobytes), but Microsoft sug-
gests using the traditional HttpClient class for these kind of files.
The process to create a file download operation involves the BackgroundDownloader class:
The settings and initialization parameters provide different ways to customize and start the
download operation. The same applies for upload operations using the BackgroundUploader
class. You can call multiple download/upload operations using these classes from the same
application because the Windows Runtime handles each operation individually.
During the operation, the application can receive events to update the UI (if the applica-
tion is still in the foreground), and you can provide a way to stop, pause, resume, or cancel
the operation. You can also read the data during the transfer operation.
These operations support credentials, cookies, and the use of HTTP headers, so you can
use them to download files from a secured location or provide a custom header to a custom
server-side HTTP handler.
The operations are managed by the Windows Runtime, promoting smart usage of power
and bandwidth. They are also independent from sudden network status changes because
they intelligently leverage connectivity and carry data-plan status information provided by
the Connectivity namespace.
The application can provide a cost-based policy for each operation using the
BackgroundTranferCostPolicy. For example, you can provide a cost policy to pause the task
automatically when the machine is using a metered network and resume it if the user comes
back to an “open” connection. The application has to do nothing to manage these situations;
it is sufficient to provide the policy to the background operation.
To enable a transfer operation in background, first enable the network in the Package.appx-
manifest file using one of the provided options in the App Manifest Designer. You must use one of
the following capabilities:
■
■ Internet (Client) The app has outbound access to the Internet and networks in pub-
lic areas, such as coffee shops, airports, and parks.
■
■ Internet (Client & Server) The app can receive inbound requests and make out-
bound requests in public areas.
■
■ Private Networks The app can receive inbound requests and make outbound re-
quests in trusted places, such as at home and work.
Figure 1-5 shows the designer with the application capabilities needed for background
data transferring.
24 CHAPTER 1 Develop Windows Store apps
FIGURE 1-5 Capabilities for background transferring
Then you can start writing code to download a file in the local storage folder. The code
excerpt in Listing 1-10 starts downloading the session1.wmv file in the Videos Library folder.
LISTING 1-10 Code to activate a background transfer
private async void Download_Click(object sender, RoutedEventArgs e)
{
try
{
var fileName = "session1.wmv";
Uri source = new Uri("http://videos.devleap.com/" + fileName);
var targetFile = await KnownFolders.VideosLibrary.CreateFileAsync(fileName,
CreationCollisionOption.GenerateUniqueName);
var downloader = new BackgroundDownloader();
var downloadOperation = downloader.CreateDownload(source, targetFile);
await downloadOperation.StartAsync();
LogOperation(String.Format("Current Download {0} to {1}, {2}",
source.AbsoluteUri, targetFile.Name, downloadOperation.Guid));
Objective 1.2: Consume background tasks CHAPTER 1 25
}
catch (Exception ex)
{
LogOperation("Download Error", ex);
}
}
The first line of code sets a local variable representing the file name to download and uses
it to create the URI for the source file. Then the CreateFileAsync method creates a file in the
user’s Videos library represented by the KnownFolders.VideosLibrary storage folder using the
async/await pattern.
The BackgroundDownloader class exposes a CreateDownload method to begin the down-
load operation: It returns a DownloadOperation class representing the current operation. The
BackgroundDownloader class exposes the StartAsync method to start the operation.
The main properties of this class are:
■
■ Guid Represents the autogenerated unique id for the download operation you can
use in the code to create a log for every download operation
■
■ RequestedUri (read-only) Represents the URI from which to download the file
■
■ ResultFile Returns the IStorageFile object provided by the caller when creating the
download operation
The BackgroundDownloader class also exposes the Pause and the Resume method as well
as the CostPolicy property to use during the background operation.
To track the progress of the download operation, you can use the provided StartAsync
method, transforming the result in a Task and passing the progress callback using an instance
of the System.Progress<T> class. Listing 1-11 shows the revised sample.
LISTING 1-11 Activating a background transfer and providing progress information
private async void Download_Click(object sender, RoutedEventArgs e)
{
try
{
var fileName = "session1.wmv";
Uri source = new Uri("http://video.devleap.com/" + fileName);
var targetFile = await KnownFolders.VideosLibrary.CreateFileAsync(fileName,
CreationCollisionOption.GenerateUniqueName);
var downloader = new BackgroundDownloader();
var downloadOperation = downloader.CreateDownload(source, targetFile);
Progress<DownloadOperation> progressCallback = new
Progress<DownloadOperation>(DownloadProgress);
26 CHAPTER 1 Develop Windows Store apps
await downloadOperation.StartAsync().AsTask(progressCallback);
LogOperation(String.Format("Current Download {0} to {1}, {2}",
source.AbsoluteUri, targetFile.Name, downloadOperation.Guid));
}
catch (Exception ex)
{
LogOperation("Download Error", ex);
}
}
private void DownloadProgress(DownloadOperation downloadOperation)
{
LogOperation(String.Format("Downloading {0} to {1}, {2}",
downloadOperation.RequestedUri, downloadOperation.Progress ,
downloadOperation.Guid)
}
In the preceding code, right after the creation of the download operation, the StartAsync
method returns the IAsyncOperationWithProgress<DownloadOperation, DownloadOperation>
interface that is transformed in a Task using the AsTask method; this method receives the
Progress<T> instance that represents the callback.
This way, the callback can receive the DownloadOperation class and can use the Guid,
RequestedUri, or ResultFile properties to track the progress or to log them (or display them if
the application is in the foreground) as appropriate for the application.
The BackgroundDownloader tracks and manages all the current download operations; you
can enumerate them using the GetCurrentDownloadAsync method.
Because the system can terminate the application, it is important to reattach the progress
and completion event handler during the next launch operation performed by the user. Use
the following code as a reference in the application launch:
IReadOnlyList<DownloadOperation> downloads = await
BackgroundDownloader.GetCurrentDownloadsAsync();
if (downloads.Count > 0)
{
List<Task> tasks = new List<Task>();
foreach (DownloadOperation download in downloads)
{
Progress<DownloadOperation> progressCallback = new
Progress<DownloadOperation>(DownloadProgress);
await download.AttachAsync().AsTask(progressCallback);
}
}
Objective 1.2: Consume background tasks CHAPTER 1 27
This method iterates through all the current download operations and reattaches the
progress callback to each of them using the AttachAsync method. The method returns an
asynchronous operation that can be used to monitor progress and completion of the at-
tached download. Calling this method enables an app to reattach download operations that
were started in a previous app instance.
Finally, you should address the time-outs enforced by the system. When establishing a
new connection for a transfer, the connection request is aborted if it is not established within
five minutes. After establishing a connection, an HTTP request message that has not received
a response within two minutes is aborted.
The same concepts apply to resource upload. The BackgroundUploader class works in a
similar way as the BackgroundDownloader class. It is designed for long-term operations on
resources such as files, images, music, and videos. As mentioned for download operations,
small resources can be uploaded using the traditional HttpClient class.
You can use CreateUploadAsync to create an asynchronous operation that, on completion,
returns an UploadOperation. There are three overloads for this method. The “BackgroundUp-
loader class” page in the MSDN official documentation provides these descriptions:
■
■ CreateUploadAsync(Uri, IIterable(BackgroundTransferContentPart)) Returns
an asynchronous operation that, on completion, returns an UploadOperation with the
specified URI and one or more BackgroundTransferContentPart objects
■
■ CreateUploadAsync(Uri, IIterable(BackgroundTransferContentPart),
String) Returns an asynchronous operation that, on completion, returns an
UploadOperation with the specified URI, one or more BackgroundTransferContentPart
objects, and the multipart subtype
■
■ CreateUploadAsync(Uri, IIterable(BackgroundTransferContentPart),
String, String) Returns an asynchronous operation that, on completion, re-
turns an UploadOperation with the specified URI, multipart subtype, one or more
BackgroundTransferContentPart objects, and the delimiter boundary value used to
separate each part
Alternatively, you can use the more specific CreateUploadFromStreamAsync that returns an
asynchronous operation that, on completion, returns the UploadOperation with the specified
URI and the source stream. This is the method definition:
public IAsyncOperation<UploadOperation> CreateUploadFromStreamAsync(
Uri uri,
IInputStream sourceStream
)
28 CHAPTER 1 Develop Windows Store apps
As for the downloader classes, this class exposes the ProxyCredential property to provide
authentication to the proxy and ServerCredential to authenticate the operation with the tar-
get server. You can use the SetRequestHeader method to specify HTTP header key/value pairs.
Keeping communication channels open
For applications that need to work in the background, such as VoIP, instant messaging, and
email, the new Windows Store application model provides an always-connected experience
for the end user. In practice, an application that depends on a long-running network connec-
tion to a remote server can still work even when the Windows Runtime suspends the appli-
cation. As you learned, a background task enables the application to perform some kind of
work in the background when the application is suspended.
Keeping a communication channel open is required for an application that sends data to
or receives data from a remote endpoint. It is also required for long-running server processes
to receive and process any incoming requests from the outside.
Typically, this kind of application sits behind a proxy, a firewall, or a Network Address
Translation (NAT) device. This hardware component preserves the connection if the endpoints
continue to exchange data: if there is no traffic for some time (it can be few seconds or min-
utes) these devices close the connection.
To ensure that the connection is not lost and remains open between server and client
endpoints, the application can be configured to use some kind of keep-alive connection (that
is, a message is sent on the network at periodic intervals) so that the connection lifetime is
prolonged.
These messages can be easily sent in previous versions of Windows because the applica-
tion stays in the Running state until the user decides to close (or terminate) it. In this scenario,
keep-alive messages can be sent without any problems. The new Windows 8 application
life-cycle management, on the contrary, does not guarantee that packets are delivered to a
suspended app. Moreover, incoming network connections can be dropped and no new traffic
is sent to a suspended app; these behaviors have an impact on the network devices that cut
the connection between apps because they become “idle” from a network perspective.
To be always connected, a Windows Store app needs to be a lock screen–capable applica-
tion. Only applications that use one or more background tasks can be lock screen apps.
An app on the lock screen can do the following:
■
■ Run code when a time trigger occurs.
■
■ Run code when a new user session is started.
■
■ Receive a raw push notification from Windows Push Notification Service and run code
when a notification is received.
■
■ Maintain a persistent transport connection in the background to remote services or
endpoints, and run code when a new packet is received or a keep-alive packet needs
to be sent using a network trigger.
Objective 1.2: Consume background tasks CHAPTER 1 29
Remember that a user can have a maximum of seven lock screen apps at any given time. A
user can also add or remove an app from the lock screen at any time.
Windows Push Notification Service (WNS) is a cloud service hosted by Microsoft for Win-
dows 8. Windows Store apps can use WNS to receive notifications that can run code, update a
live tile, or raise an on-screen notification. To use WNS, the local computer must be connect-
ed to the Internet so that the WNS service can communicate with it. A Windows Store app
in the foreground can use WNS to update live tiles, raise notifications to the user, or update
badges. Apps do not need to be on the lock screen to use WNS. You should consider using
WNS in your app if it must run code in response to a push notification.
MORE INFO WINDOWS PUSH NOTIFICATION SERVICE (WNS)
For a complete discussion of WNS, see Chapter 3, “Program user interaction.”
The ControlChannelTrigger class in the System.Net.Sockets namespace implements the trig-
ger for applications that must maintain a persistent connection to a remote endpoint: Use this
feature if the application cannot use WNS. For example, an email application that uses some
POP3 servers cannot be modified to use a push notification because the server does not
implement WNS and does not send messages to POP3 clients.
The ControlChannelTrigger can be used by instances of one of the following classes:
MessageWebSocket, StreamWebSocket, StreamSocket, HttpClient, HttpClientHandler, and
related classes in the System.Net.Http namespace in .NET Framework 4.5. The IXML-
HTTPRequest2, an extension of the classic XMLHttpRequest, can also be used to activate a
ControlChannelTrigger.
The main benefits of using a network trigger are compatibility with existing client/server
protocols and the guarantee of message delivery. The drawbacks are a little more complex in
respect to WNS, and the maximum number of triggers an app can use is five in the current
version of the Windows Runtime.
EXAM TIP
An application written in JavaScript cannot use a ControlChannelTrigger if it uses other
background tasks.
An application that uses a network trigger needs to request the lock screen permission.
This feature supports two different resources for a trigger:
■
■ Hardware slot The application can use background notification even when the de-
vice is in low-power mode or standby (connected to a plug).
■
■ Software slot The application cannot use network notification when not in low-
power mode or standby (connected to a plug).
30 CHAPTER 1 Develop Windows Store apps
This resource capability provides a way for your app to be triggered by an incoming noti-
fication even if the device is in low-power mode. By default, a software slot is selected if the
developer does not specify an option. A software slot enables your app to be triggered when
the system is not in connected standby. This is the default on most computers.
There are two trigger types:
■
■ Push notification network trigger Enables a Windows Store app to process incom-
ing network packets on an already established TCP socket, even if the application is
suspended. This socket, which represents the control channel that exists between the
application and a remote endpoint, is created by the application to trigger a back-
ground task when a network packet is received by the application. In practice, the
control channel is a persistent TCP/IP connection maintained alive by the Windows
Runtime even if the application is sent in the background and suspended.
■
■ Keep-alive network trigger Enables a suspended application to send keep-alive
packets to a remote service or endpoint. To avoid connection cutting, the keep-alive
packets tell the network device that a connection is still in use.
Before using a network trigger, the application has to be a lock screen app. You need to
declare application capability and then call the appropriate method to ask the user for per-
mission to place the application on the lock screen.
NOTE LOCK SCREEN REMOVAL
You also have to handle a situation in which the user removes the application from the lock
screen.
To register an application for the lock screen, ensure that the application has a WideLogo
definition in the application manifest on the DefaultTile element:
<DefaultTile ShowName="allLogos" WideLogo="AssetswideLogo.png" />
Add a LockScreen element that represents the application icon on the lock screen inside
the VisualElements node in the application manifest:
<LockScreen Notification="badge" BadgeLogo="AssetsbadgeLogo.png" />
You can use the App Manifest Designer, shown in Figure 1-6, to set these properties. The
Wide Logo and the Badge Logo reference the relative images, and the Lock Screen Notifica-
tions element is set to Badge.
Objective 1.2: Consume background tasks CHAPTER 1 31
FIGURE 1-6 Badge and wide logo definition
Declare the extensions to use a background task, and define the executable file that
contains the task and the name of the class implementing the entry point for the task. The
task has to be a controlChannel background task type. For this kind of task, the executable
32 CHAPTER 1 Develop Windows Store apps
file is the application. Apps using the ControlChannelTrigger rely on in-process activation for
background task. The following code declares the background task:
Sample of XML code
<Extensions>
<Extension Category="windows.backgroundTasks"
Executable="$targetnametoken$.exe"
EntryPoint="ControlChannelTriggerTask.ReceiveTask">
<BackgroundTasks>
<Task Type="controlChannel" />
</BackgroundTasks>
</Extension>
</Extensions>
The dynamic-link library (DLL) or the executable file that implements the task for keep-
alive or push notifications must be linked as a WinRT component (WinMD library). You can
also use the App Manifest Designer to set these extensions in an easier way, as shown in
Figure 1-7.
FIGURE 1-7 Background tasks app settings
The next step is to ask the user for permission to become a lock screen application using
the RequestAccessAsync method of the BackgroundExecutionManager class of the Windows.
ApplicationModel.Background namespace. See Listing 1-12. The call to this method presents a
dialog box to the user to approve the request.
Another Random Document on
Scribd Without Any Related Topics
follow him by the plain trail he'll leave. We'll come to our breakfast in
less than ten minutes."
Phil soon saw that Breakstone was right. The trail on the other
side of the salt spring was plain and red, and presently they found
the great stag in a thicket, lying upon his side, stone dead, Bill
Breakstone was an adept at cleaning and dressing, and soon the
ugly work was over. They always carried matches, and Phil quickly
lighted a fire of dry sticks that burned up rapidly and that soon made
a fine heap of glowing coals.
"Now," said Breakstone, "we'll cook and eat, then we'll cook and
eat again, then we'll cook and eat once more."
"And I don't care very much whether Comanches heard the rifle
shot or not," said Phil. "It seems to me that when I eat as much as I
want I can whip the whole Comanche nation."
"I feel that way, too," said Bill Breakstone, "but the Comanches
didn't hear. I know it in my bones. Didn't I tell you about that streak
of luck? Luck's coming our way now, and the streak will last for
awhile."
They cut long twigs, sharpened them at the ends, and fried over
the coals strips of the deer, which gave out such a rich aroma as
they sputtered that the two could scarcely restrain themselves. Yet
they did it, they remained white men and gentlemen, and did not
guzzle.
"Phil," said Bill, before he took a single bite, "I remember about
that dinner in New Orleans you were talking of so long ago. I
remember about those beautiful oysters, those splendid fish from
the gulf, the gorgeous Virginia ham, the magnificent Louisiana
turkey; yes, I remember all those magnificent fripperies and
frummeries, but it seems to me if they were all set down before us,
spread on a service of golden plate, they wouldn't be finer than what
is now awaiting us."
"Bill," said Phil with deep emphasis and unction, "you never
spoke truer words in your life."
"Then lay on, Macduff, and the first who cries 'hold, enough'--
well, he won't be much of a trencherman."
They fell to. They did not eat greedily, but they ate long and
perseveringly. Strip after strip was fried over the coals, gave out its
savory odor, and disappeared. Phil occasionally replenished the fire,
adding to the bed of coals, but keeping down the smoke. Bill,
stretching his long body on the ground and then propping himself up
on his elbow, concluded that it was a beautiful world.
"Didn't I tell you our luck would hold for awhile?" he repeated.
"Since we got into the woods, things have come easy. A good bed
put itself right in our way, then a deer walked up and asked to be
eaten.
"The deer
It was here.
One shot--
In our pot.
"We haven't any pot, but you can use things in a metaphorical sense
in order to get your rhyme. That's what poetry is for."
"I'm beginning to feel satiated," said Phil.
"'Satiated' is a good word," said Bill Breakstone, "but it isn't
used much on the plains. Still, I'm beginning to feel that way myself,
too, and I think we'd better begin to consider the future, which is
always so much bigger than the present."
"We must find our horses."
"Of course, and after that we must find the train, which will be
our chief problem. It may be where we left it or it may have gone
on, thinking that we had been killed by some outlying party of
Comanches. But I don't believe Middleton and Arenberg would move
without us. They may now be somewhere in these woods looking for
us."
"Can you figure out the direction of the valley in which we left
our horses?"
Breakstone studied the sun attentively.
"It's southeast from here," he replied, "and I fancy it's not more
than three or four miles. Two likely lads like you and me ought to
find it pretty soon, and, nine chances out of ten, the horses will be
there. We'll take some of the best portions of the deer with us, and
start at once."
They chose the choicest pieces of the meat and started, now
strong of body and light of heart. Phil's own judgment about the
direction agreed with Breakstone's, and in less than an hour they
saw familiar ground.
"I'm a good prophet to-day," said Breakstone. "I've got the gift
for a few hours at least. I predicted truly about the deer, and now I
am going to predict truly about the horses. We'll have them by the
bridle inside of half an hour."
In fifteen minutes they were in the little valley, in three minutes
they found the horses grazing peacefully, and in two more minutes
they caught them.
"We've done the work and with ten minutes to spare," said Bill
Breakstone, triumphantly, "and now, Phil, another wonderful change
in our fortunes has come. If a camel is the ship of the desert, then a
horse is the boat of the plains, the long boat, the jolly boat, the row
boat, and all the rest of them. Now for the wagon train!"
"Now for the wagon train!" repeated Phil.
CHAPTER VIII
NEW ENEMIES
The two were in splendid spirits. They had escaped great dangers,
and they were on horseback once more. It is true, they were
somewhat short on armament, but Breakstone took Phil's pistol,
while the latter kept the rifle, and they were confident that they
could find game enough on the plains until they overtook the wagon
train. The horses themselves seemed glad of the companionship of
their old masters, and went forward readily and at an easy pace
through the woods. They soon found the path by which they had
come, and followed it until they crossed the river and reached the
site of the camp. But the trail toward the plain lay before them broad
and easy.
"They can't have gone long," said Breakstone. "They may have
thought that we were merely loitering behind for some purpose of
our own and would soon overtake them. A whole train isn't going to
linger about for two fellows well mounted and well armed who are
supposed to know how to take care of themselves. But, Sir Philip of
the Youthful Countenance, I don't think that Middleton and Arenberg
would go ahead without us."
"Neither do I," said Phil with emphasis. "I as good as know that
they're looking for us in these woods, and we've got to stay behind
and find them, taking the risk of Comanches."
"Wherein I do heartily agree with you, and I'm going to take a
chance right now. It is likely that the two, after fruitless searches for
us, would return here at intervals, and, in a region like this, the
sound of a shot will travel far. Fire the rifle, Phil, and it may bring
them. It's often used as a signal. If it brings the Comanches instead,
we're on our horses, and they're strong and swift."
Phil fired a shot, but there was no response. He waited half an
hour and fired a second time, with the same result. After another
half hour, the third shot was fired, and, four or five minutes later,
Breakstone announced that he heard the tread of hoofs. It was a
faint, distant sound, but Phil, too, heard it, and he was confident
that it was made by hoofs. The two looked at each other, and each
read the question in the other's eye. Who were coming in reply to
the call of that third rifle shot, red men or white?
"We'll just draw back a little behind this clump of bushes," said
Breakstone. "We can see a long way through their tops, and not be
seen until the riders come very close. Then, if the visitors to this
Forest of Arden of ours, Sir Philip, are not those whom we wish to
see, it's up and away with us."
They waited in strained eagerness. The sounds grew louder. It
was certain, moreover, that the riders were coming straight toward
the point at which the rifle had been fired.
"Judging from the hoof beats, how many would you say they
are?" asked Phil.
"Not many. Maybe three or four, certainly not more. But I'm
hoping that it's two, neither more nor less."
On came the horsemen, the hoofbeats steadily growing louder.
Phil rose in his stirrups and gained a further view. He saw the top of
a soft hat and then the top of another. In a half minute the faces
beneath came into view. He knew them both, and he uttered a cry
of joy.
"Middleton and Arenberg!" he exclaimed. "Here they come!"
"Our luck still holds good," said Bill Breakstone. He and Phil
galloped from behind the bushes and shouted as warm a welcome
as men ever had. They received one equally warm in return, as
Middleton and the German urged their horses forward. Then there
was a mighty shaking of hands and mutual congratulations.
"The train left yesterday morning," said Middleton, "but we
couldn't give you up. We scouted all the way across the forest and
saw the Comanches on the other side. There was nothing to indicate
anything unusual among them, such as a sacrifice of prisoners, and
we hoped that if you had been taken by them you had escaped, and
we came back here to see, knowing that if you were able you would
return to this place. We were right in one part of our guess, because
here you are."
"And mighty glad we are to be here," said Bill Breakstone, "and
I want to say to you that I, Bill Breakstone, who may not be of so
much importance to the world, but who is of vast importance to
himself, would not be here at all, or anywhere else, for that matter, if
it were not for this valiant and skillful youth, Sir Philip Bedford,
Knight of the Texas plains."
"Stop, Bill," exclaimed Phil blushing. "Don't talk that way."
"Talk that way! Of course I will! And I'll pile it up, too! And after
I pile it up and keep on piling it up, it won't be the whole truth. Cap,
and you, Hans, old fellow, Phil and I were not taken together,
because Phil was never taken at all. It was I alone who sat still, shut
my eyes, and closed my ears while I let three of the ugliest
Comanche warriors that were ever born walk up, lay violent hands
on me, harness me up in all sorts of thongs and withes, and carry
me off to their village, where they would have had some red sport
with me if Phil hadn't come, when they were all mad with a great
dance, and taken me away."
Then he told the story in detail, and Phil, shy and blushing, was
compelled to receive their compliments, which were many and
sincere. But he insisted that he merely succeeded through good
luck, which Bill Breakstone warmly denied.
"Well, between the two of you, you have certainly got out of it
well," said Middleton, "and, as we are reunited, we must plan for the
next step. We can easily overtake the train by to-morrow, but I'm of
the opinion that we'll have to be very careful, and that we must do
some scouting, also. Arenberg and I have discovered that the
Comanche warriors are on the move again. Their whole force of
warriors seemed to be getting ready to leave the village, and they
may be planning, after all, a second attack upon the train, a night
surprise, or something of that kind. We, too, will have to be careful
lest we run into them."
"Then it maybe for the good of the train that we were left back
here," said Phil, "because we will return with a warning."
"It may be the hand of Providence," said Arenberg, "since the
Comanches did no harm where much was intended."
As both Middleton and Arenberg were firmly convinced that the
plain would be thick with Comanche scouts, making their passage by
daylight impossible, or at least extremely hazardous, they decided to
remain in the woods until nightfall. They rode a couple of miles from
the camp, tethered their horses in thick bushes, and, sitting near
them, waited placidly. Phil Breakstone, and Arenberg talked in low
tones, but Middleton sat silent. Phil noticed presently that "The Cap"
was preoccupied. Little lines of thought ran down from his eyes to
the corners of his nose.
Phil began to wonder again about the nature of Middleton's
mission. Every one of the four was engaged upon some great quest,
and none of them knew the secret of any of the others. Nor, in the
rush of events, had they been left much time to think about such
matters.
Now Phil again studied Middleton more closely. There was
something in the unaccustomed lines of his face and his thoughtful
eye indicating a belief that for him, at least, the object of the quest
might be drawing nigh. At least, it seemed so to the boy. He studied,
too, Middleton's clean cut face, and the sharp line of his strong chin.
Phil had noticed before that this man was uncommonly neat in his
personal appearance. It was a neatness altogether beyond what one
usually saw on the plains. His clothing was always clean and in
order, he carried a razor, and he shaved every day. Nor did he ever
walk with a slovenly, lounging gait.
Phil decided that something very uncommon must have sent
him with the Santa Fé train, but he would not ask; he had far too
much delicacy to pry into the secret of another, who did not pry into
his own.
Middleton and Arenberg had ample food in their saddlebags and
Phil and Breakstone combined with it their stock of deer meat.
Nothing disturbed them in the thicket, and at nightfall they mounted
and rode out into the plain.
"I know something about this country before us," said
Breakstone. "It runs on in rolling swells for a march of many days,
without any streams except shallow creeks, and without any timber
except the fringes of cottonwoods along these creeks."
"And I know which way to go in order to overtake the train,"
said Middleton. "Woodfall said that they would head straight west,
and we are certainly good enough plainsmen to keep our noses
pointed that way."
"We are, we surely are," said Bill Breakstone, "but we must
keep a good watch for those Comanche scouts. They hide behind
the swells on their ponies, and they blend so well with the dusky
earth that you'd never notice 'em until they had passed the signal on
to others that you were coming and that it was a good time to form
an ambush."
There was a fair sky, with a moon and some clear stars, and
they could see several hundred yards, but beyond that the whole
horizon fused into a dusky wall. They rode at a long, swinging pace,
and the hoofs of their horses made little noise on the new spring
turf. The wind of the plains, which seldom ceases, blew gently in
their faces and brought with it a soft crooning sound. Its note was
very pleasant in the ears of Philip Bedford. In the saddle and with
his best friends again, he felt that he could defy anything. He felt,
too, and perhaps the feeling was due to his physical well-being and
recovered safety, that he, also, was coming nearer to the object of
his quest. Involuntarily he put his left hand on his coat, where the
paper which he had read so often lay securely in a little inside
pocket. He knew every word of it by heart, but when the time came,
and he was alone, he would take it out and read it again. It was this
paper that was always calling to him.
They rode on, crossing swell after swell, and, after the first
hour, the four did not talk. It was likely that every one was thinking
of his own secret.
They came about midnight to a prairie creek, a stream of water
two or three yards wide and a few inches deep, flowing in a bed of
sand perhaps fifteen yards across. A thin fringe of low cottonwoods
and some willows grew on either shore. They approached warily,
knowing that such a place offered a good ambush, and realizing that
four would not have much chance against a large Comanche war
band.
"But I don't think there is much danger," said Bill Breakstone. "If
the Comanches are up to mischief again, they're not looking for
stray parties; their mind is on the train, and, by the way, the train
has passed along here. Look down, and in this moonlight you can
see plainly enough the tracks of a hundred wheels."
"The horses are confident," said Middleton, "and I think we can
be so, too."
The horses were advancing without hesitation, and it soon
became evident that nothing was concealed among the scanty lines
of trees and bushes.
"Look out for quicksands," said Arenberg. "It iss not pleasant to
be swallowed up in one of them and feel that you have died such a
useless death."
"There is no danger," said Phil, whose quick eye was following
the trail of the wagons. "Here is where the train crossed, and if the
wagons didn't sink we won't."
The water being cold and entirely free from alkali, the horses
drank eagerly, and their riders, also, took the chance to refill their
canteens, which they always carried strapped to their saddle bows.
They also rested awhile, but, when they remounted and rode on,
Middleton noticed a light to the northward. On the plains then, no
man would pass a light without giving it particular attention, and the
four sat on their horses for some minutes studying it closely. They
thought at first that it might be a signal light of the Comanches, but,
as it did not waver, they concluded that it must be a camp fire.
"Now I'm thinking," said Bill Breakstone, "that we oughtn't to
leave a camp fire burning away here on the plains, and we not
knowing anything about it. It won't take us long to ride up and
inspect it."
"That is a truth," said Middleton. "It is not a difficult matter for
four horsemen to overtake a wagon train, but we'll first see what
that fire means."
"It iss our duty to do so," said the phlegmatic German.
They rode straight toward the light, and their belief that it was a
camp fire was soon confirmed. They saw the red blaze rising and
quivering, and then dusky figures passing and repassing before it.
"We're yet too far away to tell exactly what those figures are,"
said Bill Breakstone, "but I don't see any sign of long hair or war
bonnets, and so I take it that they are not Comanches, nor any
other kind of Indians, for that matter. No warriors would build so
careless a fire or wander so carelessly about it.
"They are white men," said Middleton with conviction, as he
increased his horse's pace. "Ah, I see now! Mexicans! Look at the
shadows of their great conical hats as they pass before the fire."
"Now I wonder what they're doing here on Texas soil," said Bill
Breakstone.
Middleton did not answer, but Phil noticed that the look in his
eyes was singularly tense and eager. As they drew near the fire,
which was a large one, and the hoof-beats of their horses were
heard, two men in Mexican. dress, tall conical broad-brimmed hats,
embroidered coats and trousers and riding boots, bearing great
spurs, came forward to meet them. Phil saw another figure, which
had been lying on a blanket by the fire, rise and stand at attention.
He instantly perceived, even then, something familiar in the figure.
The four rode boldly forward, and Middleton called out:
"We are friends!"
The two Mexicans who were in advance, rifle in hand, stood
irresolutely, and glanced at the man behind them, who had just risen
from his blanket.
"You are welcome," said this man in good English but with a
strong Mexican accent. "We are glad for anybody to share with us
our camp fire in this wilderness. Dismount, Señores."
Then Phil knew him well. It was Pedro de Armijo, the young
Mexican whom he had seen with the Mexican envoy, Zucorra, in New
Orleans, one whom he had instinctively disliked, one whom he was
exceedingly astonished to see at such a time and place. Middleton
also recognized him, because he raised his cap and said politely:
"This is a pleasant meeting. You are Captain Pedro de Armijo,
who came to our capital with His Excellency Don Augustin Xavier
Hernando Zucorra on a mission, intended to be of benefit to both
our countries. My name is Middleton, George Middleton, and these
are my friends, Mr. Breakstone, Mr. Arenberg, and Mr. Bedford."
De Armijo gave every one in turn a quick scrutinizing look, and,
with flowing compliment, bade them welcome to his fireside. It
seemed that he did not remember Middleton, but that he took for
granted their former meeting in Washington. Phil liked him none the
more because of the polite words he used. He was not one to hold
prejudice because of race, but this Mexican had a manner
supercilious and conceited that inspired resentment.
"It seems strange, Señor Middleton," said de Armijo, "that we
should meet again in such a place on these vast plains, so far from a
house or any other human beings, plains that were once Mexican,
but which you now call yours."
De Armijo glided over the last words smoothly, but the blood
leaped in Phil's temples. Middleton apparently took no notice, but
said that he and his comrades were riding across the plains mainly
on an exploring expedition. As there was some danger from
Comanches, they were traveling partly by night, and, having seen
the camp fire, they had come to investigate it, after the custom of
the wilderness.
"And, now that you have found us," said de Armijo with
elaborate courtesy, "I have reason to believe that you would run into
Comanche horsemen a little farther on. They would not harm us
Mexicans, with whom they are at peace, but for you Americans they
would have little mercy. Stay with us for the remainder of the night."
He smiled, showing his white teeth, and Middleton smiled back
as he replied:
"Your courtesy is appreciated, Captain de Armijo. We shall stay.
It is pleasant, too, to welcome a gallant Mexican officer like yourself
to American soil."
The eyes of de Armijo snapped in the firelight, and the white
teeth were bared again. Phil knew that he resented the expression
"American soil." Mexico still maintained a claim to Texas--which it
could not make good--and he felt equally confident that Middleton
had used it purposely. It seemed to him that some sort of duel was
in progress between the two, and he watched it with overwhelming
curiosity. But de Armijo quickly returned to his polite manner.
"You speak the truth," he said. "It is I who am your guest, not
you who are mine. It was Mexican soil once, and before that
Spanish--three centuries under our race--but now gone, I suppose,
forever."
Middleton did not reply, but approached the fire and warmed his
hands over the blaze. The night was cold and the flames looked
cheerful. The others tethered their horses, and all except the two
who had met the Americans took their places by the fire. The
Mexicans were six in number. Only de Armijo seemed to be a man of
any distinction. The others, although stalwart and well armed, were
evidently of the peon class. Phil wondered what this little party was
doing here, and the conviction grew upon him that the meeting had
something to do with Middleton's mission.
"I am sorry," said de Armijo, "that we do not even have a tent
to offer you, but doubtless you are accustomed to sleeping under
the open sky, and the air of these plains is dry and healthy."
"A blanket and a few coals to warm one's feet are sufficient,"
said Middleton. "We will avail ourselves of your courtesy and not
keep you awake any longer."
Both Breakstone and Arenberg glanced at Middleton, but they
said nothing, wrapping themselves in their blankets, and lying down,
with their feet to the fire. Phil did the same, but he thought it a
strange proceeding, this apparently unguarded camping with
Mexicans, who at the best were not friends, with the possibility of
Comanches who were, at all times, the bitterest and most dangerous
of enemies. Yet Middleton must have some good reason, he was not
a man to do anything rash or foolish, and Phil awaited the issue with
confidence.
Phil could not sleep. The meeting had stirred him too much, and
his nerves would not relax. He lay before the fire, his feet within a
yard of the coals, and his head in the crook of his arm. Now and
then he heard a horse move or stamp his hoofs, but all the men
were silent. De Armijo, lying on a blanket and with a fine blue
cavalry cloak spread over him, seemed to be asleep, but as he was
on the other side of the fire Phil could not see his eyes. Middleton
was nearer, and he saw his chest rising and falling with the
regularity of one who sleeps.
It all seemed very peaceful, very restful. Perhaps de Armijo's
hospitality was real, and he had wronged him with his suspicions.
But reason with himself as he would, Phil could not overcome his
dislike and distrust. Something was wrong, and something was going
to happen, yet much time passed and nothing happened. De
Armijo's eyes were still shaded by his cloak, but his long figure lay
motionless. Only a few live coals remained from the fire, and beyond
a radius of twenty feet lay the encircling rim of the darkness. At the
line where light and dark met, crouched the two peons with their
rifles across their knees. It was Phil's opinion that they, too, slept in
this sitting posture. Surely de Armijo and his men had great
confidence in their security, and must be on the best of terms with
the Comanches! If so, it might increase the safety of the little
American party, also, but the boy yet wondered why Middleton had
stopped when they were all so eager to reach the wagon train and
warn it of the new danger.
Phil stirred once or twice, but only to ease his position, and he
did it without noise. His eyes were shaded by the brim of his soft
hat, but he watched the circle about the fire, and most of all he
watched de Armijo. An interminable period of time passed, every
second growing to ten times its proper length. Phil was as wakeful
as ever, but so much watching made the figures about the fire dim
and uncertain. They seemed to shift their places, but the boy was
still resolved to keep awake, although everybody else slept through
the night. His premonition was yet with him, his heart expanded,
and his pulse beat faster.
The remaining coals died one by one. The circle of light, already
small, contracted still more, became a point, and then vanished.
Everything now lay in the dark, and the figures were merely blacker
shapes against the blackness. Then, after that long waiting, with
every second and minute drawn out tenfold, Phil's premonition came
true. Something happened.
De Armijo moved. He moved ever so slightly, but Phil saw him,
and, lying perfectly still himself, he watched him with an absorbed
attention, and a heart that had increased its beating still further. De
Armijo's body itself had not moved, it was merely one hand that had
come slowly from under the covering of the cloak, and that now lay
white against the blue cloth. A man might move his hand thus in
sleep, but it seemed to Phil that the action was guided by a
conscious mind. Intent, he watched, and presently his reward came.
The other hand also slid from beneath the cloak, and, like its fellow,
lay white against the blue cloth. Now both hands were still, but Phil
yet waited, confident that more would come. It was all very quiet
and slow, like the craft and cunning of the Indian, but Phil was
willing to match it with a patience and craft of his own.
At last the whole figure of de Armijo stirred. Phil saw the blue
cloak tremble slightly. Then the man raised his head ever so little
and looked about the dark circle. Slowly he let the head fall back,
and the figure became still again. But the boy was not deceived.
Already every suspicion had been verified in his mind, and his
premonition was proved absolutely true.
Pedro de Armijo raised himself again, but a little higher this
time, and he did not let his head and body drop back. He looked
about the circle with a gaze that Phil knew must be sharp and
scrutinizing, although it was too dark for him to see the expression
of his eyes. The Mexican seemed satisfied with his second
examination, and then, dropping softly on his hands and knees, he
crept toward Middleton. It occurred to Phil afterward that this
approach toward Middleton did not surprise him. In reality, it was
just what he had expected de Armijo to do.
The boy was uncertain about his own course, and, like one
under a spell, he waited. The dusky figure of de Armijo creeping
toward Middleton had a sinuous motion like that of a great snake,
and Phil's hand slipped down to the hammer of his rifle, but he
would not fire. He noticed that de Armijo had drawn no weapon, and
he did not believe that murder was his intention.
Middleton did not move. He lay easily upon his right side, and
Phil judged that he was in a sound sleep. De Armijo, absorbed in his
task, did not look back. Hence he did not see the boy who rose
slowly to a sitting posture, a ready rifle in his hands.
Phil saw de Armijo reach Middleton's side and pause there a
moment or two. He still drew no weapon, and this was further proof
that murder was not in the Mexican's mind, but Phil believed that
whatever lay between these two was now at the edge of the crisis.
He saw de Armijo raise his hand and put it to Middleton's breast with
the evident intention of opening his coat. So he was a thief! But the
fingers stopped there as Phil leveled his rifle and called sharply:
"Hands up, de Armijo, or I shoot!"
The startled Mexican would have thrown up his hands, but he
did not have time. They were seized in the powerful grasp of
Middleton, and he was pulled downward upon his face.
"Ah, would you, de Armijo!" cried Middleton in exultant tones.
"We have caught you! Good boy, Phil, you were watching, too!"
"All the others were up in an instant, but Breakstone and
Arenberg were too quick for the Mexicans. They covered them with
their rifle muzzles before their antagonists could raise their weapons.
"Throw down every gun and pistol!" said Breakstone sternly.
"There, by the log, and we'll see what's going forward!"
Sullenly the Mexicans complied, and then stood in a little
huddled group, looking at their fallen leader, whom Middleton still
held upon the ground, but who was pouring out muffled oaths from
a face that was in the dirt.
"Take his pistols, Phil," said Middleton, and the boy promptly
removed them. Then Middleton released him, and de Armijo sat up,
his face black as night, his heart raging with anger, hate, and
humiliation.
"How dare you attack me in my own camp! You whom we
received as guests!" he cried.
"We did not attack you," replied Middleton calmly. He had risen
to his feet, and he towered over the Mexican like an accusing judge.
"It is you who attacked us, or me, rather, and you intended, if you
did not get what you wanted with smooth fingers, to use violence.
You cannot deny that, Captain Pedro de Armijo of the Mexican army;
there were at least two witnesses of your act, Philip Bedford and
myself."
De Armijo looked down at the ground, and seemed to commune
with himself for a few moments. Then he stood at his full height,
brushed the traces of dirt from his clothes, and gave Middleton a
look of uncompromising defiance and hostility. All at once it struck
Phil that this was a man of ability and energy, one who could be a
bitter and dangerous enemy.
"You are right in part, Captain Middleton," said de Armijo slowly.
"I was seeking to take the maps, letters, and instructions that you
carry inside your tunic, next, perhaps, to your very flesh. They would
be valuable possessions to us, and it was my duty, as a captain in
the Mexican army, to take them if I could, from you, a captain in the
American army."
Phil started and looked anew at Middleton. A captain in the
American army! This was why he had walked with that upright
carriage! This was why he had been so particular about his personal
appearance! He began to see a little way.
"We, too, have our channels of information," said de Armijo,
"and I knew that you had embarked upon a mission in the West to
learn our movements and forces upon the border, and our temper
and disposition with regard to great matters that are agitating both
Mexico and America."
"It is true, all that you say," replied Middleton tranquilly. "I am
Captain George Middleton of the American regular troops, and, at
the request of our War Department, I undertook the hazardous
mission of which you speak."
"You will go no farther with it," said de Armijo.
"How can you keep me from it?"
"I cannot--perhaps, but events can--events have. You do not
know, but I do, Captain Middleton, that there is war between your
country and mine."
"Ah!" exclaimed Middleton, and, despite the darkness, Phil saw
a sudden flush spring into his face.
"It is not only war," continued de Armijo, "but there has been a
heavy battle, two of them, in fact. Your troops met ours at Palo Alto
on May eighth, and again on the following day at Resaca de la
Palma."
"Ah!" exclaimed Middleton again, the exclamation being drawn
up from the very depths of his being, while the flush on his face
deepened. "And you know, I suppose, which won?"
It was a peculiar coincidence that the moon's rays made their
way at that moment through clouds, and a bright beam fell on the
face of Pedro de Armijo. Phil saw the Mexican's face fall a little,
despite all his efforts at self-control. De Armijo himself felt this
change in his countenance, and, knowing what it indicated to the
man who asked the question, he replied without evasion:
"I regret to say that the fortunes of war were against the
deserving. Our brave general, Ampudia, and our gallant troops were
compelled to retire before your general, Taylor. At least, so say my
hasty advices; perhaps they are wrong."
But Phil could see that de Armijo had no such hope. The news
was correct, and the boy's heart thrilled with joy because the first
victories had fallen to his own people.
"I would not have told you this," continued de Armijo, "had you
not caught me in an attempt to take your papers. Had it been peace,
'steal' would have been the word, but since it is war 'steal' turns to
enterprise and zeal. Had I not believed you ignorant that the war
has begun, and that I might make more profit out of you in our
hands than as a fugitive, or at least as one who might have escaped,
I should have opened fire upon you as you approached. Perhaps I
made a mistake."
"All of us do at times," said Middleton thoughtfully.
"Well spoken," said de Armijo. He lighted a cigarette and took a
few easy puffs.
"Well, Captain Middleton," he said at length, "the problem is
now yours, not ours. You have taken it out of our hands. What are
you going to do with us?"
"It seems to me," said Captain Middleton, "that this problem,
like most others, admits of only one solution. You are our prisoners,
but we cannot hold you. Our own situation prevents it. We could kill
you, but God forbid a single thought of such a crime. We will take
your arms and let you go. You will not suffer without your arms, as
your Comanche friends are near, a fact which you know very well."
"We accept your terms," said de Armijo, "since we must, and
with your permission we will mount our horses and ride away. But it
is to be understood, Captain Middleton, and you, young Mr. Bedford,
and the rest of you, that we part as enemies and not as friends."
"As you will," said Middleton. "I recognize the fact that you have
no cause to love us, and perhaps the sooner we both depart from
this spot the better it will be for all."
"But we may meet again on the battlefield; is it not so?" said de
Armijo.
"That, I cannot tell," replied Middleton, "but it is not unlikely."
Breakstone and Arenberg still stood by the captured arms, but,
without casting a glance at either the arms or their guardians, de
Armijo signaled to his men, and they mounted and rode away.
"Adios!" he called back in Spanish, although he did not turn his
face.
"Adios!" said Middleton in the same tone.
They did not move or speak until they heard the hoof-beats die
away, and then it was Bill Breakstone who first broke the silence.
"That certainly came out well," he said. "The curtain came down
on a finer finish than the first act indicated. I confess that I didn't
know your plan, Captain--I don't call you Cap any more--but I
trusted you, and I confess, also, that I fell asleep. It was you and Sir
Philip of the Active Mind and the Watchful Eye who did most of the
work.
"It was in Tex.
We met the Mex.
They spoke so high,
But now they cry.
Or, at least, they ought to cry when they think how we turned the
tables on them. Now, Captain, I suppose we must be up and doing,
for those fellows, as you said, will go straight to the Comanches, and
if we linger here our scalps will be of less value to ourselves than to
anybody else."
"It is quite true," said Captain Middleton. "We must reach the
train as soon as possible, because the danger to it has increased
with our own. But even more important than that is the great
change that must be made. Woodfall cannot go on now, since the
whole Southwest will be swept by bands of Mexican and Indian
horsemen."
"What must the train do?" asked Phil in anxiety, because this
concerned him very nearly.
"It must turn south and join the American army on the Rio
Grande. Most of the things that it carries will be of value to our
troops, and Woodfall will clear as much profit there as at Santa Fé,
which is now a city in arms against us. In this case the path of
comparative safety and honor is also the path of profit. What more
could Woodfall ask?"
"He's a brave man, and brave men are with him," said Bill
Breakstone. "You won't have to ask him twice."
Phil's heart had throbbed with joy at Middleton's answer. His
quest was always in his mind. He had feared that they might turn
back, but now it suited him as well to join the American army as to
go on toward Santa Fé. The quest was a wide one. But Arenberg
suppressed a sigh.
"Let's be starting," said Middleton. "We'll take their arms with
us. They're of value, and Bill, moreover, is without a rifle or musket."
Breakstone, who had been examining the weapons, uttered a
cry of joy.
"Here is a fine rifle," he said, "one of the best American make. I
wonder how that Mexican got it! The rest are not so good."
"Take the fine one, Bill," said Middleton, "and we will pack up
the rest and ride."
They were out of the woods in a few minutes, and again rode
rapidly toward the west. It was an easy task to pick up the great
wagon trail again, even in the dark of the night, as the grass and soil
were trodden or pressed down over a width of fully two hundred
yards. The country rolled lightly. Bill Breakstone thought that a range
of hills lay toward the north, but in the night they could not see.
"I hope that we'll overtake Woodfall before day," said Middleton,
"because I've an idea that de Armijo and the little band with him are
not the only Mexicans hereabouts. He would not come so far North
without a considerable force, and I suspect that it is his intention to
capture our train, with the aid of the Comanches."
"We can beat them off," said Breakstone confidently.
"If our people are warned in time," said Middleton.
"Much harm iss meant," said Arenberg, speaking for the first
time, "but we may keep much from being done. Our most dangerous
enemies before the daylight comes are the Comanches. They have
already learned from de Armijo that we are here, and it iss like as
not that they are now between us and the train."
Middleton looked at his watch, holding it in the moon's rays.
"It is two hours until day," he said, "and the trail is rapidly
growing fresher. We may yet get through before the ring closes. Ah,
there they are now!"
A hand's breadth of fire suddenly leaped up in the north, and
burned there like a steady torch. Far in the east, another but fainter
appeared and burned, and a third leaped up in the south. But when
they looked back in the west they saw none.
"Fortune rides on our cruppers so far," said Middleton. "We are
on the side of the circle which yet has the open segment. Push on,
my boys!"
Phil's knees involuntarily pressed against the side of his horse,
and that strange sensation, like icy water running down the spine,
came again. Those three lights speaking to one another in the
darkness and across great distances were full of mystery and awe.
But he rode without speech, and he looked most of the time at the
lights, which remained fixed, as if what they said could not be
changed.
Middleton, who was in advance, suddenly reined in his horse,
and the others, stopping, also, noticed that just in front of them a
depression ran across the plain.
"It's an arroyo or something like it," said Bill Breakstone, "but
the wagons have crossed it anyhow."
They followed the trail to the other side and then saw that it
continued almost parallel with the broad gully.
"Why shouldn't we take to the gully?" said Phil. "It has a smooth
bottom, it is wide enough for us, riding two abreast, and it will give
us shelter."
"A good idea," said Middleton.
They turned back into the arroyo, and found an easy road there.
The banks were several feet high, and, as the dusk still hung on the
plain, they increased their speed, counting each moment worth one
man's life. They came soon to a place where the gully was shallower
than usual, and then they saw two or three faint lights in the plain
before them, apparently about a half mile away. Middleton raised a
warning hand, and they stopped.
"Those are the lights of the train," he said. "They undoubtedly
have scouts out, and of course they have seen the signals of the
Comanches and the Mexicans, just as we have, but they do not
know as much as we do. I think we had better go down the arroyo
as far as we can, and then, if the alarm is sounded by our enemies,
gallop for it."
"It iss our choice because there iss none other," said Arenberg.
They continued, but more slowly, in order to make as little noise
as possible. They had covered more than half the distance when Phil
saw a faint line of gray on the horizon line in the east. The next
moment against the background of gray appeared a horseman, a
man of olive skin, clad in sombrero, bright jacket, embroidered
trousers, and boots with great spurs. He carried a weapon like a
spear, and Phil knew at once that he was a Mexican lancer, no doubt
a sentinel.
The man saw them, and, instead of attempting to use his lance,
snatched a pistol from his belt and fired point blank. The bullet
passed by Middleton's face, and, like a flash, Bill Breakstone replied
with a bullet from his rifle. The Mexican went down, but from three
points of the compass came cries, the shouts of the Mexicans and
the long war whoop of the Comanches.
"Forward for your lives!" cried Middleton, and, dashing out of
the arroyo, they galloped at full speed toward the wagon train.
CHAPTER IX
THE FIERY CIRCLE
The thin gray light in the east broadened into a bar as the hoofbeats
of the four thundered over the plain. From left to right came shouts,
the yells of the Indians and the fierce cries of the Mexicans.
"Bend low," cried Middleton, "and we may escape their bullets!"
Phil lay almost upon his horse's neck, but it was an unconscious
act. He was thrilling with excitement, as the four horsemen almost
clove the morning mist, and rode on swift hoofs straight toward the
wagon train. Then came the rattling of rifles and whistling of arrows
from either side. "Ping!" the bullets sang in his ear and "Ping!" the
arrows sang, also. He remembered afterward that he wished, if he
were hit at all, to be hit by a bullet instead of an arrow; an arrow
sticking in one's flesh would be very cumbersome and painful. But
neither arrow nor bullet struck true. Their ride was too sudden and
swift, and the light too faint to permit good aim to the Mexicans and
Comanches. Yet Phil heard confused sounds, shouted commands,
and the noise of hurrying feet. He saw dark faces appearing in the
mist on either side, and he also saw the outlines of wagons through
the same mist in front. Then he saw men, rifle in hand, who seemed
to rise out of the plain in front of the wagons. Two of the men raised
their rifles and took aim at the galloping horsemen.
"We are friends, and we bring you warning!" shouted Middleton
in a tremendous voice. "Don't fire upon us!"
But the men and three others who appeared near them pulled
the trigger. Phil did not hear the ping of the bullets, and now he
realized that they fired not at his comrades and himself but at those
who pursued. A death-cry and yells of rage came from behind them,
but in another minute they were within the line of sentinels and
were springing from their horses, ready to take their part in the
combat that they expected.
All the morning mists were driven away at that moment by the
sun, as if a veil had been lifted, and the whole plain stood out clear
and distinct under a brilliant sky. Before them were the wagons,
drawn up in a circle in the customary fashion of a camp, the horses
and mules in the center, and the men, arms in hand, forming an
outer ring for the wagons. But from the northeast and the southeast
two lines were converging upon them, and Phil's heart kindled at the
sight.
The line in the northeast was made up of red horsemen, four
hundred Comanches, naked to the waist, horribly painted, and riding
knee to knee, the redoubtable chiefs, Santana and Black Panther, at
their head. The line in the southeast was composed of Mexican
cavalry, lancers splendidly mounted, the blades of their lances and
their embroidered jackets glittering in the sun. They made their
horses prance and cavort, and many in the first rank whirled lariats
in derision.
A tall figure strolled forward and welcomed Middleton and his
comrades. It was Woodfall, his face flushed somewhat, but his
manner undaunted.
"I'm glad to welcome you back, Mr. Middleton," he said, "and
with your comrades, all of them alive and well. But what does this
mean? Why do those men ride to attack, when this is the soil of
Texas?"
He waved his hand toward the advancing Mexican column.
"They advance against us," replied Middleton, "because this is
war, war between the United States and Mexico--we learned that last
night from one of their own officers--and there have been two heavy
battles on the Rio Grande, both victorious for us."
It was not strange that a sudden cheer burst from the men who
heard these words. Woodfall listened to it grimly, and, when it died,
he said:
"Then if these Mexicans attack, we'll soon have a third victory to
our credit. The Indian bow and the Mexican lance can't break
through a circle of riflemen, entrenched behind wagons--riflemen
who know how to shoot."
Again that defiant, even exultant cheer rose from the men who
heard, and, passing on like a fire in dry grass, it rolled all around the
circle of wagons. The Mexicans heard it. They detected the defiant
note in it, and, wisely, they checked their speed. The column of
Indian warriors also came more slowly. Philip Bedford, hardened in
so brief a space to danger and war, did not feel any great fear, but
the scene thrilled him like a great picture painted in living types and
colors against the background of the earth. There were the red
horsemen, the sun deepening the tints of their coppery faces and
bringing out the glowing colors of their war bonnets. To the
southeast the Mexican column, also, was a great ribbon of light lying
across the plain, the broad blades of the lances catching the sun's
rays and throwing them back in golden beams.
"A fine show," said Woodfall, "and if those Mexicans had two or
three cannon they might wipe us out, but they haven't, and so we're
lucky."
"I think I ought to tell you, Mr. Woodfall," said Middleton, "that
I'm a captain in the regular army, Captain Middleton, and that I've
been making use of your hospitality to find what forces the enemy
had in these parts, and what movements he was making. I was sent
by our government, and, as you see, I'm finding what I was sent to
find."
"I thought there was something military about your cut,
Captain," said Woodfall, "and it seems to me to be a good thing that
you are with us. If we've helped you without knowing, then you,
knowing it, can help us now."
The hands of the two men met in the strong clasp of friendship
and trust.
"They're about to move," said Middleton, who practically took
command. "I suggest that we go inside the circle of wagons now,
and that at least two-thirds of our men devote their attention to the
lancers. The Mexicans are brave; we must not forget that."
They went inside at once, where a few men were detailed to
see that the horses and mules did not make too great a turmoil,
while the rest posted themselves for defense. The wagons were in
reality a formidable barrier for an attacking force that did not have
artillery. The majority of the Americans lay down under the wagons
between the wheels. Phil was under one of them with Bill
Breakstone on one side of him and Arenberg on the other. Middleton
was elsewhere with Woodfall.
"Much harm iss meant," said Arenberg, "and I would say to you,
Philip, although little advice iss needed by you now, not to fire too
soon, and to remember, when you take aim, to allow for the fact
that they are coming toward us at a gallop."
"That's right," said Bill Breakstone. "Old Hans, here, knows."
"Ach," said Arenberg, uttering a sigh, "I love peace, and I never
thought to have a part in cruel Indian and Mexican battles."
It occurred to Phil that the sigh had no reference to the coming
combat. The German's face showed sadness, but not a trace of fear.
He turned his gaze from Arenberg and fixed it upon the Mexican
column which they were facing. He thought that he saw de Armijo in
the front rank among the officers in brilliant dress, but he was not
sure. The distance was too great. He wondered whether he would
shoot at him, if he saw him later in the charge.
The sunlight was intensely bright, such as one sees only on
great upland plains, and the Mexican lancers with their horses stood
out, like carving, against the background of gold and blue. Phil saw
the column suddenly quiver, as if a single movement ran through all.
The lances were lifted a little higher, and their blades cast broader
beams. A flag fluttered in the front rank and unfolded in the slight
wind.
The notes of a trumpet sounded high and clear, the Mexicans
uttered a long, fierce shout, the colors shifted and changed, like
water flowing swiftly, as the column broke into a gallop and came
straight toward the wagons, the plain thundering with the beat of
their hoofs. From another part of the compass came a second cry,
higher pitched, longer drawn, and with more of the whine of the
wolf in it. Phil knew that it came from the Comanches, who were
also charging, led by Black Panther and Santana, but he did not take
his eyes from the Mexicans.
The two attacking columns began to fire scattering shots, but
the defenders of the wagons had not yet pulled a trigger, although
many a forefinger was trembling with eagerness.
"It's pretty, but it's a waste, a dead waste," said Bill Breakstone.
"I hate to shoot at them, because I've no doubt many a brave young
fellow is out there, but we've got to let them have it. Steady, Phil,
steady! They're coming close now."
Suddenly they heard the loud shout, "Fire!" It was Middleton
who uttered it, and everybody obeyed. A sheet of flame seemed to
spurt from the wagons, and the air was filled with singing lead. The
entire head of the Mexican column was burnt away. The ground was
strewn with the fallen. Riderless horses, some wounded and
screaming with pain, galloped here and there. The column stopped
and seemed to be wavering. Several officers, sword in hand--and
now Phil was sure that he saw de Armijo among them--were trying
to urge the lancers on. All the Americans were reloading as fast as
they could, and while the Mexicans yet wavered, they poured in a
second volley. Unable to withstand it, the lancers broke and fled,
bearing the officers away with them in their panic.
Phil, Bill Breakstone, and Arenberg crawled from under the
wagon and stood on the outside, erect again. There they
contemplated for a few moments the wreck that they and their
comrades had made. From the Indian point of attack came the
sound of retiring shots, and they knew that the Comanches had
been quickly repulsed, also.
"It was one of the most foolish things I ever saw," said Bill
Breakstone, "to ride right into the mouths of long-barreled, well-
aimed rifles like ours. Their numbers didn't help them. What say
you, Sir Philip of the Rifle and the Wagon?"
"It seems to me that you're right," replied the boy. "I don't think
they'll charge again, nor will the Comanches."
"You're right, too; they've had enough."
The Mexicans and Comanches, having gathered up their
wounded, united and remained in a dark cloud beyond rifle shot,
apparently intending neither to charge again nor to go away. But the
defenders of the train were cheerful. They had suffered no loss,
being protected so well, and they were willing enough to meet a
second attack delivered in the same fashion. But Middleton and
Woodfall had hot coffee and tea served, and then with strong field
glasses they observed the enemy.
"I believe they are in great doubt," said Middleton. "They may
think they can starve us out, but the Mexicans will not want to wait
for so long a process; it is likely that they will prefer going
southward to join their main army."
He said these words aloud, where many could hear, but a little
while afterward he and Woodfall drew to one side and talked a long
time in low tones. Phil could tell by their faces that they were very
earnest, and he felt sure that a proposition would be made before
long. He called Breakstone's attention to them.
"You're right," said Bill, "they'll have something to say soon, and
it will concern all of us. Ah, there comes the Cap--I mean the
Captain--now, and he's going to make a speech."
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
More than just a book-buying platform, we strive to be a bridge
connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.
Join us on a journey of knowledge exploration, passion nurturing, and
personal growth every day!
ebookbell.com

More Related Content

PDF
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthy
PDF
Exam Ref 70413 Designing And Implementing A Server Infrastructure Steve Suehring
PDF
Programming Windows Store Apps with C 1st Edition Matthew Baxter-Reynolds
PDF
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st ...
PDF
Programming Windows Store Apps with C 1st Edition Matthew Baxter-Reynolds
PDF
Android Application Development Programming With The Google Sdk 1st Edition R...
PDF
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st ...
PDF
Learning React Native Building Native Mobile Apps with JavaScript 2nd Edition...
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthy
Exam Ref 70413 Designing And Implementing A Server Infrastructure Steve Suehring
Programming Windows Store Apps with C 1st Edition Matthew Baxter-Reynolds
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st ...
Programming Windows Store Apps with C 1st Edition Matthew Baxter-Reynolds
Android Application Development Programming With The Google Sdk 1st Edition R...
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st ...
Learning React Native Building Native Mobile Apps with JavaScript 2nd Edition...

Similar to Exam Ref 70485 Advanced Windows Store App Development Using C Roberto Brunetti (20)

PDF
Beginning android application development wei meng lee
PDF
Learning React Native Building Native Mobile Apps With Javascript 2nd Edition...
PDF
Code In The Cloud 1st Edition Mark C Chucarroll
PDF
Learning React Native Building Native Mobile Apps with JavaScript 2nd Edition...
PDF
Microsoft Visual Basic Programs To Accompany Programming Logic And Design 3rd...
PDF
Programming Flex 2 Chafic Kazoun Joey Lott
PDF
Code in the Cloud 1st Edition Mark C. Chu-Carroll
PDF
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
PDF
Exam Ref 70687 Configuring Windows 81 Joli Ballew
PDF
Download ebooks file Code in the Cloud 1st Edition Mark C. Chu-Carroll all ch...
PDF
Download full ebook of Learning Node Shelley Powers instant download pdf
PDF
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
PDF
Programming Embedded Systems With C And Gnu Development Tools 2nd Edition 2nd...
PDF
Code in the Cloud 1st Edition Mark C. Chu-Carroll
PDF
Code in the Cloud 1st Edition Mark C. Chu-Carroll
PDF
Programming Ios 5 2nd Edition 2nd Early Release Draft Matt Neuburg
PDF
Addressing identity, access and compliance requirements using ibm tivoli iden...
PDF
Learning Swift 3 Early release 3rd Edition Jonathan Manning
PDF
Programming Logic and Design Comprehensive 6th Edition Joyce Farrell
PDF
Windows Server 2003 best practices for enterprise deployments 1st Edition Dan...
Beginning android application development wei meng lee
Learning React Native Building Native Mobile Apps With Javascript 2nd Edition...
Code In The Cloud 1st Edition Mark C Chucarroll
Learning React Native Building Native Mobile Apps with JavaScript 2nd Edition...
Microsoft Visual Basic Programs To Accompany Programming Logic And Design 3rd...
Programming Flex 2 Chafic Kazoun Joey Lott
Code in the Cloud 1st Edition Mark C. Chu-Carroll
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
Exam Ref 70687 Configuring Windows 81 Joli Ballew
Download ebooks file Code in the Cloud 1st Edition Mark C. Chu-Carroll all ch...
Download full ebook of Learning Node Shelley Powers instant download pdf
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
Programming Embedded Systems With C And Gnu Development Tools 2nd Edition 2nd...
Code in the Cloud 1st Edition Mark C. Chu-Carroll
Code in the Cloud 1st Edition Mark C. Chu-Carroll
Programming Ios 5 2nd Edition 2nd Early Release Draft Matt Neuburg
Addressing identity, access and compliance requirements using ibm tivoli iden...
Learning Swift 3 Early release 3rd Edition Jonathan Manning
Programming Logic and Design Comprehensive 6th Edition Joyce Farrell
Windows Server 2003 best practices for enterprise deployments 1st Edition Dan...
Ad

Recently uploaded (20)

PDF
2.FourierTransform-ShortQuestionswithAnswers.pdf
PDF
Insiders guide to clinical Medicine.pdf
PDF
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
PPTX
1st Inaugural Professorial Lecture held on 19th February 2020 (Governance and...
PDF
TR - Agricultural Crops Production NC III.pdf
PDF
Computing-Curriculum for Schools in Ghana
PDF
RMMM.pdf make it easy to upload and study
PDF
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
PDF
01-Introduction-to-Information-Management.pdf
PDF
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
PPTX
Lesson notes of climatology university.
PDF
FourierSeries-QuestionsWithAnswers(Part-A).pdf
PPTX
master seminar digital applications in india
PPTX
Renaissance Architecture: A Journey from Faith to Humanism
PDF
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
PDF
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
PPTX
Final Presentation General Medicine 03-08-2024.pptx
PPTX
PPH.pptx obstetrics and gynecology in nursing
PPTX
human mycosis Human fungal infections are called human mycosis..pptx
PPTX
Microbial diseases, their pathogenesis and prophylaxis
2.FourierTransform-ShortQuestionswithAnswers.pdf
Insiders guide to clinical Medicine.pdf
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
1st Inaugural Professorial Lecture held on 19th February 2020 (Governance and...
TR - Agricultural Crops Production NC III.pdf
Computing-Curriculum for Schools in Ghana
RMMM.pdf make it easy to upload and study
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
01-Introduction-to-Information-Management.pdf
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
Lesson notes of climatology university.
FourierSeries-QuestionsWithAnswers(Part-A).pdf
master seminar digital applications in india
Renaissance Architecture: A Journey from Faith to Humanism
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
Final Presentation General Medicine 03-08-2024.pptx
PPH.pptx obstetrics and gynecology in nursing
human mycosis Human fungal infections are called human mycosis..pptx
Microbial diseases, their pathogenesis and prophylaxis
Ad

Exam Ref 70485 Advanced Windows Store App Development Using C Roberto Brunetti

  • 1. Exam Ref 70485 Advanced Windows Store App Development Using C Roberto Brunetti download https://ebookbell.com/product/exam-ref-70485-advanced-windows- store-app-development-using-c-roberto-brunetti-4428712 Explore and download more ebooks at ebookbell.com
  • 2. Here are some recommended products that we believe you will be interested in. You can click the link to download. Exam Ref 70741 Networking With Windows Server 2016 Andrew Warren https://ebookbell.com/product/exam-ref-70741-networking-with-windows- server-2016-andrew-warren-46508894 Exam Ref 70533 Implementing Microsoft Azure Infrastructure Solutions Michael Washam Rick Rainey Dan Patrick Steve Ross https://ebookbell.com/product/exam-ref-70533-implementing-microsoft- azure-infrastructure-solutions-michael-washam-rick-rainey-dan-patrick- steve-ross-50200546 Exam Ref 70533 Implementing Microsoft Azure Infrastructure Solutions Washam https://ebookbell.com/product/exam-ref-70533-implementing-microsoft- azure-infrastructure-solutions-washam-22029870 Exam Ref 70532 Developing Microsoft Azure Solutions Tejada Zoinerbustamante https://ebookbell.com/product/exam-ref-70532-developing-microsoft- azure-solutions-tejada-zoinerbustamante-22066954
  • 3. Exam Ref 70740 Installation Storage And Compute With Windows Server 2016 Kellington https://ebookbell.com/product/exam-ref-70740-installation-storage-and- compute-with-windows-server-2016-kellington-22066956 Exam Ref 70765 Provisioning Sql Databases Joseph Dantoni https://ebookbell.com/product/exam-ref-70765-provisioning-sql- databases-joseph-dantoni-22066962 Exam Ref 70345 Designing And Deploying Microsoft Exchange Server 2016 Paul Cunningham Brian Svidergol https://ebookbell.com/product/exam-ref-70345-designing-and-deploying- microsoft-exchange-server-2016-paul-cunningham-brian- svidergol-33325406 Exam Ref 70484 Essentials Of Developing Windows Store Apps Using C Indrajit Chakrabarty https://ebookbell.com/product/exam-ref-70484-essentials-of-developing- windows-store-apps-using-c-indrajit-chakrabarty-37206148 Exam Ref 70762 Developing Sql Databases Louis Davidson Stacia Varga https://ebookbell.com/product/exam-ref-70762-developing-sql-databases- louis-davidson-stacia-varga-38623980
  • 7. Exam Ref 70-485: Advanced Windows Store App Development Using C# Roberto Brunetti Vanni Boncinelli
  • 8. Published with the authorization of Microsoft Corporation by: O’Reilly Media, Inc. 1005 Gravenstein Highway North Sebastopol, California 95472 Copyright © 2013 by Roberto Brunetti and Vanni Boncinelli All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission of the publisher. ISBN: 978-0-7356-7686-2 1 2 3 4 5 6 7 8 9 QG 8 7 6 5 4 3 Printed and bound in the United States of America. Microsoft Press books are available through booksellers and distributors worldwide. If you need support related to this book, email Microsoft Press Book Support at mspinput@microsoft.com. Please tell us what you think of this book at http://www.microsoft.com/learning/booksurvey. Microsoft and the trademarks listed at http://www.microsoft.com/about/legal/ en/us/IntellectualProperty/Trademarks/EN-US.aspx are trademarks of the Microsoft group of companies. All other marks are property of their respec- tive owners. The example companies, organizations, products, domain names, email ad- dresses, logos, people, places, and events depicted herein are fictitious. No association with any real company, organization, product, domain name, email address, logo, person, place, or event is intended or should be inferred. This book expresses the author’s views and opinions. The information con- tained in this book is provided without any express, statutory, or implied warranties. Neither the authors, O’Reilly Media, Inc., Microsoft Corporation, nor its resellers, or distributors will be held liable for any damages caused or alleged to be caused either directly or indirectly by this book. Acquisitions Editor: Jeff Riley Developmental Editor: Kim Lindros Production Editor: Kristen Brown Editorial Production: Box Twelve Communications Technical Reviewer: Luca Regnicoli Copyeditor: Nancy Sixsmith Indexer: Angie Martin Cover Design: Twist Creative • Seattle Cover Composition: Ellie Volckhausen Illustrator: Rebecca Demarest
  • 9. This book is dedicated to my parents. — Roberto Brunetti This book is dedicated to my family. — Vanni Boncinelli
  • 11. Contents at a glance Introduction xv Chapter 1 Develop Windows Store apps 1 Chapter 2 Discover and interact with devices 57 Chapter 3 Program user interaction 131 Chapter 4 Enhance the user interface 193 Chapter 5 Manage data and security 275 Chapter 6 Prepare for a solution deployment 335 Index 415 About the authors 443
  • 13. vii What do you think of this book? We want to hear from you! Microsoft is interested in hearing your feedback so we can continually improve our books and learning resources for you. To participate in a brief online survey, please visit: www.microsoft.com/learning/booksurvey/ Contents Introduction xv Microsoft certifications xv Acknowledgments xv Errata & book support xvi We want to hear from you xvi Stay in touch xvi Chapter 1 Develop Windows Store apps 1 Objective 1.1: Create background tasks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Creating a background task 2 Declaring background task usage 5 Enumerating registered tasks 7 Using deferrals with tasks 7 Objective summary 8 Objective review 8 Objective 1.2: Consume background tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Understanding task triggers and conditions 9 Progressing through and completing background tasks 11 Understanding task constraints 14 Cancelling a task 15 Updating a background task 18 Debugging tasks 19 Understanding task usage 21 Transferring data in the background 22 Keeping communication channels open 28 Objective review 37
  • 14. viii Contents Objective 1.3: Create and consume WinMD components. . . . . . . . . . . . . . 38 Understanding the Windows Runtime and WinMD 38 Consuming a native WinMD library 40 Creating a WinMD library 46 Objective summary 50 Objective review 50 Chapter summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Chapter 2 Discover and interact with devices 57 Objective 2.1: Capture media with the camera and microphone. . . . . . . . 57 Using CameraCaptureUI to capture pictures or video 58 Using MediaCapture to capture pictures, video, or audio 68 Objective summary 79 Objective review 80 Objective 2.2: Get data from sensors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Understanding sensors and location data in the Windows Runtime 81 Accessing sensors from a Windows Store app 81 Determining the user’s location 99 Objective summary 108 Objective review 108 Objective 2.3: Enumerate and discover device capabilities. . . . . . . . . . . . 109 Enumerating devices 110 Using the DeviceWatcher class to be notified of changes to the device collection 117 Enumerating Plug and Play (PnP) devices 122 Objective summary 124 Objective review 124 Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
  • 15. ix Contents Chapter 3 Program user interaction 131 Objective 3.1: Implement printing by using contracts and charms. . . . . 131 Registering a Windows Store app for the Print contract 132 Handling PrintTask events 137 Adding the user interface 138 Creating a custom print template 140 Understanding the print task options 142 Paginating and previewing the document 144 Choosing options to display in the preview window 148 Reacting to print option changes 149 Adding custom print options 152 Implementing in-app printing 153 Objective summary 154 Objective review 154 Objective 3.2: Implement Play To by using contracts and charms . . . . . 155 Introducing the Play To contract 156 Testing sample code using Windows Media Player on a different machine 159 Implementing a Play To source application 161 Registering your app as a Play To receiver 167 Objective summary 174 Objective review 175 Objective 3.3: Notify users by using Windows Push Notification Service (WNS). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Requesting and creating a notification channel 176 Sending a notification to the client 178 Objective summary 186 Objective review 187 Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
  • 16. x Contents Chapter 4 Enhance the user interface 193 Objective 4.1: Design for and implement UI responsiveness. . . . . . . . . . 193 Understanding .NET asynchronous patterns 194 Writing methods using async techniques 202 Implementing asynchronous methods 204 Waiting for an event in an asynchronous way 207 Implementing asynchronous calls 208 Cancelling asynchronous operations 209 Cancelling an operation in asynchronous calls 210 Tracking operation progress 211 Tracking progress in asynchronous operations 212 Synchronizing multiple asynchronous calls 215 Waiting for multiple asynchronous calls executed in parallel 217 Choosing the right SynchronizationContext in libraries 218 Objective summary 220 Objective review 220 Objective 4.2: Create animations and transitions. . . . . . . . . . . . . . . . . . . . 221 Creating and customizing storyboarded animations 222 Exploring dependent animations vs. independent animations 225 Creating key-frame animations 228 Using interpolations and easing functions in animations 229 Using discrete animations 232 Applying animations from the animation library 233 Objective summary 238 Objective review 238 Objective 4.3: Create custom controls. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Adding a custom control to your Windows Store app 239 Creating your own dependency properties for a custom control 243 Reacting to changes in the visual state of the custom control 246 Objective summary 251 Objective review 251
  • 17. xi Contents Objective 4.4: Design Windows Store apps for globalization and localization. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 Planning for globalization 252 Localizing your app 256 Localizing your manifest 265 Using the Multilingual App Toolkit 265 Objective summary 267 Objective review 267 Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Chapter 5 Manage data and security 275 Objective 5.1: Design and implement data caching. . . . . . . . . . . . . . . . . . 275 Understanding application and user data 275 Caching application data 276 Understanding Microsoft rules for using roaming profiles with Windows Store apps 286 Caching user data 287 Objective summary 290 Objective review 290 Objective 5.2: Save and retrieve files from the file system. . . . . . . . . . . . 291 Using file pickers to save and retrieve files 291 Accessing files and data programmatically 298 Working with folders, files, and streams 300 Setting file extensions and associations 301 Compressing files to save space 304 Objective summary 305 Objective review 306 Objective 5.3: Secure app data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306 Introducing the Windows.Security.Cryptography namespaces 307 Using hash algorithms 308 Generating random numbers and data 311 Encrypting messages with MAC algorithms 313 Using digital signatures 316
  • 18. xii Contents Enrolling and requesting certificates 319 Protecting your data with the DataProtectionProvider class 325 Objective summary 328 Objective review 329 Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330 Chapter 6 Prepare for a solution deployment 335 Objective 6.1: Design and implement trial functionality in an app. . . . . 335 Choosing the right business model for your app 336 Exploring the licensing state of your app 338 Using custom license information 344 Purchasing an app 345 Handling errors 349 Setting up in-app purchases 350 Retrieving and validating the receipts for your purchases 356 Objective summary 358 Objective review 358 Objective 6.2: Design for error handling . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 Handling exceptions in the .NET Framework 359 Catching errors and exceptions at the application level 361 Handling device capability errors 364 Handling asynchronous errors 368 Objective summary 373 Objective review 374 Objective 6.3: Design and implement a test strategy. . . . . . . . . . . . . . . . . 374 Understanding functional testing vs. unit testing 375 Implementing a test project for a Windows Store app 378 Objective summary 387 Objective review 387
  • 19. xiii Contents Objective 6.4: Design a diagnostics and monitoring strategy. . . . . . . . . 388 Profiling a Windows Store app and collecting performance counters 388 Tracing and logging events for Windows Store apps 398 Using Windows Store reports to improve the quality of your app 402 Objective summary 405 Objective review 406 Chapter summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407 Answers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408 Index 415 What do you think of this book? We want to hear from you! Microsoft is interested in hearing your feedback so we can continually improve our books and learning resources for you. To participate in a brief online survey, please visit: www.microsoft.com/learning/booksurvey/
  • 21. xv Introduction The Microsoft 70-485 certification exam tests your knowledge of Windows Store application development using C#. Readers are assumed to be Windows Store app developers with deep knowledge of the Windows Runtime architecture, the application life cycle managed by the system (including suspend, termination, resume, and launch), the Visual Studio 2012 project structure, the application manifest, app deployment, and Windows Store requirements. The reader must have also a strong background in XAML and C#. This book covers every exam objective, but it does not cover every exam question. Only the Microsoft exam team has access to the exam questions themselves, and Microsoft regu- larly adds new questions to the exam, making it impossible to cover specific questions. You should consider this book a supplement to your relevant real-world experience and other study materials. If you encounter a topic in this book that you do not feel completely com- fortable with, use the links you’ll find in text to find more information and take the time to research and study the topic. Great information is available on MSDN, TechNet, and in blogs and forums. Microsoft certifications Microsoft certifications distinguish you by proving your command of a broad set of skills and experience with current Microsoft products and technologies. The exams and corresponding certifications are developed to validate your mastery of critical competencies as you design and develop, or implement and support, solutions with Microsoft products and technologies both on-premise and in the cloud. Certification brings a variety of benefits to the individual and to employers and organizations. MORE INFO All Microsoft certifications For information about Microsoft certifications, including a full list of available certifica- tions, go to http://www.microsoft.com/learning/en/us/certification/cert-default.aspx. Acknowledgments I’d like to thank Vanni for his side-by-side work. He has shared with me all the intricacies of writing a book with this level of detail. — Roberto Brunetti
  • 22. xvi Introduction I’d like to thank Roberto for teaching me everything I know today about software develop- ment, and Marika for her support and infinite patience during the writing of this book. — Vanni Boncinelli Roberto and Vanni want to thank all the people who made this book possible. In particu- lar, we thank Kim Lindros, for her exceptional support throughout the editing process of this book; Jeff Riley, for giving us this opportunity; and Russell Jones, for introducing our team to Jeff. Special thanks to Wouter de Kort for providing some of the content in Chapter 4. Errata & book support We’ve made every effort to ensure the accuracy of this book and its companion content. Any errors that have been reported since this book was published are listed on our Microsoft Press site at oreilly.com: http://aka.ms/ER70-485/errata If you find an error that is not already listed, you can report it to us through the same page. If you need additional support, email Microsoft Press Book Support at mspinput@microsoft.com. Please note that product support for Microsoft software is not offered through the ad- dresses above. We want to hear from you At Microsoft Press, your satisfaction is our top priority, and your feedback our most valuable asset. Please tell us what you think of this book at: http://www.microsoft.com/learning/booksurvey The survey is short, and we read every one of your comments and ideas. Thanks in ad- vance for your input! Stay in touch Let’s keep the conversation going! We’re on Twitter: http://twitter.com/MicrosoftPress.
  • 23. 1 C H A P T E R 1 Develop Windows Store apps In this chapter, you learn how to create background tasks and implement the appropriate interfaces for a Windows Store app. You also find out how to consume them using timing and system triggers, request lock screen access, and create download and upload opera- tions using the BackgroundTransfer class. The last part of the chapter is dedicated to creat- ing and consuming WinMD components. Objectives in this chapter: ■ ■ Objective 1.1: Create background tasks ■ ■ Objective 1.2: Consume background tasks ■ ■ Objective 1.3: Create and consume WinMD components Objective 1.1: Create background tasks Windows 8 changes the way applications run. Windows Store application life-cycle manage- ment of the Windows Runtime (WinRT) is different from previous versions of Windows: only one application (or two in snapped view) can run in the foreground at a time. The system can suspend or even terminate other apps from the Windows Runtime. This behavior forces the developer to use different techniques to implement some form of background work, such as to download a file or perform tile updates. This section covers how to implement a background task using the provided classes and interfaces, and how to code a simple task. This objective covers how to: ■ ■ Create a background task ■ ■ Use the Windows.ApplicationModel.Background classes ■ ■ Implement the IBackgroundTask interface
  • 24. 2 CHAPTER 1 Develop Windows Store apps Creating a background task In Windows Store apps, when users work on an app in the foreground, background apps can- not interact directly with them. In fact, due to the architecture of Microsoft Windows 8 and because of the application life-cycle management of Windows Store apps, only the foreground app has the focus and is in the running state; the user can choose two applications in the fore- ground using the snapped view. All the other background apps can be suspended and even terminated by the Windows Runtime. A suspended app cannot execute code, consume CPU cycles or network resources, or perform disk activity such as reading or writing files. You can define a background task that runs in the background, however, even in a separate process from the owner app, and you can define background actions. When these actions need to alert users about their outcomes, they can use a toast. A background task can execute code even when the corresponding app is suspended, but it runs in an environment that is restricted and resource-managed. Moreover, background tasks receive only a limited amount of system resources. You should use a background task to execute small pieces of code that require no user interaction. You can also use a background task to communicate with other apps via instant messaging, email, or Voice over IP (VoIP). Avoid using a background task to execute complex business logic or calculations because the amount of system resources available to back- ground apps is limited. Complex background workloads consume battery power as well, reducing the overall efficiency and responsiveness of the system. To create a background task, you have to define a class and register it with the oper- ating system. To do this, create a Windows Metadata (WinMD) project and then create a class in it. A background task is a public and not-inheritable class that implements the IBackgroundTask interface defined by the Windows Runtime and is registered by using a BackgroundTaskBuilder class instance. MORE INFO WINMD WinMD is covered in the section titled “Objective 1.3: Create and consume WinMD compo- nents” later in this chapter. The IBackgroundTask imposes the implementation of a single self-explaining method: Run. Listing 1-1 shows the implementation of this interface in a sample class. LISTING 1-1 Class skeleton for IBackground task interface implementation using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.ApplicationModel.Background; namespace BikeGPS {
  • 25. Objective 1.1: Create background tasks CHAPTER 1 3 public sealed class BikePositionUpdateBackgroundTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { // Update the GPS coordinates } } } You have to assign the event that will fire the task. When the event occurs, the operating system calls the defined Run method. You can associate the event, called a trigger, via the SystemTrigger or the MaintenanceTrigger class. The code is straightforward. Using an instance of the BackgroundTaskBuilder class, associ- ate the name of the task and its entry point by using the syntax namespace.class. The entry point represents the background task class, as shown in the following code: Sample of C# code var taskName = "bikePositionUpdate"; var builder = new BackgroundTaskBuilder(); builder.Name = taskName; builder.TaskEntryPoint = "BikeGPS.BikePositionUpdateBackgroundTask"; You must also create the trigger to let the system know when to start the background task: builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false)); The SystemTrigger class accepts two parameters in its constructor. The first parameter of the trigger is the type of system event associated with the background task; the second, called oneShot, tells the Windows Runtime to start the task only once or every time the event occurs. The complete enumeration, which is defined by the SystemTriggerType enum, is shown in Listing 1-2. LISTING 1-2 Types of system triggers // Summary: // Specifies the system events that can be used to trigger a background task. [Version(100794368)] public enum SystemTriggerType { // Summary: // Not a valid trigger type. Invalid = 0, // // Summary: // The background task is triggered when a new SMS message is received by an // installed mobile broadband device. SmsReceived = 1, // // Summary: // The background task is triggered when the user becomes present. An app must // be placed on the lock screen before it can successfully register background // tasks using this trigger type.
  • 26. 4 CHAPTER 1 Develop Windows Store apps UserPresent = 2, // // Summary: // The background task is triggered when the user becomes absent. An app must // be placed on the lock screen before it can successfully register background // tasks using this trigger type. UserAway = 3, // // Summary: // The background task is triggered when a network change occurs, such as a // change in cost or connectivity. NetworkStateChange = 4, // // Summary: // The background task is triggered when a control channel is reset. An app must // be placed on the lock screen before it can successfully register background // tasks using this trigger type. ControlChannelReset = 5, // // Summary: // The background task is triggered when the Internet becomes available. InternetAvailable = 6, // // Summary: // The background task is triggered when the session is connected. An app must // be placed on the lock screen before it can successfully register background // tasks using this trigger type. SessionConnected = 7, // // Summary: // The background task is triggered when the system has finished updating an // app. ServicingComplete = 8, // // Summary: // The background task is triggered when a tile is added to the lock screen. LockScreenApplicationAdded = 9, // // Summary: // The background task is triggered when a tile is removed from the lock screen. LockScreenApplicationRemoved = 10, // // Summary: // The background task is triggered when the time zone changes on the device // (for example, when the system adjusts the clock for daylight saving time). TimeZoneChange = 11, // // Summary: // The background task is triggered when the Microsoft account connected to // the account changes. OnlineIdConnectedStateChange = 12, } You can also add conditions that are verified by the system before starting the back- ground task. The BackgroundTaskBuilder class exposes the AddCondition method to add a
  • 27. Objective 1.1: Create background tasks CHAPTER 1 5 single condition, as shown in the following code sample. You can call it multiple times to add different conditions. builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable)); The last line of code needed is the registration of the defined task: BackgroundTaskRegistration taskRegistration = builder.Register(); Declaring background task usage An application that registers a background task needs to declare the feature in the applica- tion manifest as an extension, as well as the events that will trigger the task. If you forget these steps, the registration will fail. There is no <Extensions> section in the application manifest of the Microsoft Visual Studio standard template by default, so you need to insert it as a child of the Application tag. Listing 1-3 shows the application manifest for the sample task implemented by the previ- ous code (see Listing 1-2). The <Extensions> section is highlighted in bold. LISTING 1-3 Application manifest <?xml version="1.0" encoding="utf-8"?> <Package xmlns="http://schemas.microsoft.com/appx/2010/manifest"> <Identity Name="e00b2bde-0697-4e6b-876b-1d611365485f" Publisher="CN=Roberto" Version="1.0.0.0" /> <Properties> <DisplayName>BikeApp</DisplayName> <PublisherDisplayName>Roberto</PublisherDisplayName> <Logo>AssetsStoreLogo.png</Logo> </Properties> <Prerequisites> <OSMinVersion>6.2.1</OSMinVersion> <OSMaxVersionTested>6.2.1</OSMaxVersionTested> </Prerequisites> <Resources> <Resource Language="x-generate"/> </Resources> <Applications> <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="BikeApp.App"> <VisualElements DisplayName="BikeApp" Logo="AssetsLogo.png" SmallLogo="AssetsSmallLogo.png" Description="BikeApp"
  • 28. 6 CHAPTER 1 Develop Windows Store apps ForegroundText="light" BackgroundColor="#464646"> <DefaultTile ShowName="allLogos" /> <SplashScreen Image="AssetsSplashScreen.png" /> </VisualElements> <Extensions> <Extension Category="windows.backgroundTasks" EntryPoint="BikeGPS.BikePositionUpdateBackgroundTask"> <BackgroundTasks> <Task Type="systemEvent" /> </BackgroundTasks> </Extension> </Extensions> </Application> </Applications> <Capabilities> <Capability Name="internetClient" /> </Capabilities> </Package> You have to add as many task elements as needed by the application. For example, if the application uses a system event and a push notification event, you must add the following XML node to the BackgroundTasks element: <BackgroundTasks> <Task Type="systemEvent" /> <Task Type="pushNotification" /> </BackgroundTasks> You can also use the Visual Studio App Manifest Designer to add (or remove) a back- ground task declaration. Figure 1-1 shows the same declaration in the designer. FIGURE 1-1 Background task declaration in the Visual Studio App Manifest Designer
  • 29. Objective 1.1: Create background tasks CHAPTER 1 7 Enumerating registered tasks Be sure to register the task you implement just once in your application. If you forget to check the presence of the task, you risk registering and executing the same task many times. To see whether a task is registered, you can iterate all the registered tasks using the BackgroundTaskRegistration class and checking for the Value property that exposes the Name property, as follows: Sample of C# code var taskName = "bikePositionUpdate"; var taskRegistered = false; foreach (var task in BackgroundTaskRegistration.AllTasks) { if (task.Value.Name == taskName) { taskRegistered = true; break; } } if (!taskRegistered) // Register the task Using deferrals with tasks If the code for the Run method is asynchronous, the background task needs to use a deferral (the same techniques of the suspend method) using the GetDeferral method, as shown in the following code: public async void Run(IBackgroundTaskInstance taskInstance) { BackgroundTaskDeferral _deferral = taskInstance.GetDeferral(); // // Start one (or more) async // Use the await keyword // await UpdateGPSCoordinatesAsync(); _deferral.Complete(); } After requesting the deferral, use the async/await pattern to perform the asynchronous work and, at the end, call the Complete method on the deferral. Be sure to perform all the work after requesting the deferral and before calling the Complete method. Otherwise, the system thinks that your job is already done and can shut down the main thread.
  • 30. 8 CHAPTER 1 Develop Windows Store apps Thought experiment Implementing background tasks In this thought experiment, apply what you’ve learned about this objective. You can find answers to these questions in the “Answers” section at the end of this chapter. Your application needs to perform some lengthy cleaning operations on temporary data. To avoid wasting system resources during application use, you want to per- form these operations in the background. You implement the code in a background thread, but notice that your application sometimes does not clean all the data when the user switches to another application. 1. Why does the application not clean the data all the time? 2. How can you solve this problem? Objective summary ■ ■ A background task can execute lightweight action invoked by the associated event. ■ ■ A task needs to be registered using WinRT classes and defined in the application manifest. ■ ■ There are many system events you can use to trigger a background task. ■ ■ You have to register a task just once. ■ ■ You can enumerate tasks that are already registered. Objective review Answer the following questions to test your knowledge of the information in this objective. You can find the answers to these questions and explanations of why each answer choice is correct or incorrect in the “Answers” section at the end of this chapter. 1. How can an application fire a background task to respond to a network state modification? A. By using a time trigger that polls the network state every minute, and checks for changes to this value B. By using a SystemTrigger for the InternetAvailable event and checking to see whether the network is present or not C. By using a SystemTrigger for the NetworkStateChange event and using false as the second constructor parameter (called oneShot) D. By using a SystemTrigger for the NetworkStateChange event and using true as the second constructor parameter
  • 31. Objective 1.2: Consume background tasks CHAPTER 1 9 2. Which steps do you need to perform to enable a background task? (Choose all that apply.) A. Register the task in the Package.appxmanifest file. B. Use the BackgroundTaskBuilder to create the task. C. Set the trigger that will fire the task code. D. Use a toast to show information to the user. 3. Is it possible to schedule a background task just once? A. Yes, using a specific task. B. No, only system tasks can run once. C. Yes, using a parameter at trigger level. D. No, only a time-triggered task can run once at certain time. Objective 1.2: Consume background tasks The Windows Runtime exposes many ways to interact with the system in a background task and many ways to activate a task. System triggers, time triggers, and conditions can modify the way a task is started and consumed. Moreover, a task can keep a communication channel open to send data to or receive data from remote endpoints. An application might need to download or upload a large resource even if the user is not using it. The application can also request lock screen permission from the user to enhance other background capabilities. This objective covers how to: ■ ■ Use timing and system triggers ■ ■ Keep communication channels open ■ ■ Request lock screen access ■ ■ Use the BackgroundTransfer class to finish downloads Understanding task triggers and conditions Many types of background tasks are available. They respond to different kinds of triggers for any kind of application, which can be the following: ■ ■ MaintenanceTrigger Raised when it is time to execute system maintenance tasks ■ ■ SystemEventTrigger Raised when a specific system event occurs
  • 32. 10 CHAPTER 1 Develop Windows Store apps A maintenance trigger is represented by the MaintenanceTrigger class. This class imple- ments the IBackgroundTrigger interface, as do other triggers available in the Windows Runtime library. The interface in this version of the Windows Runtime declares nothing, but will be implemented in future versions of the library. To create a new instance of a trigger, you can use the following code: MaintenanceTrigger taskTrigger = new MaintenanceTrigger(60, true); The first parameter is the freshnessTime expressed in minutes, and the second parameter, called oneShot, is a Boolean indicating whether the trigger should be fired only one time or every freshnessTime occurrence. Whenever a system event occurs, you can check a set of conditions to determine whether your background task should execute. When a trigger is fired, the background task does not run until all its conditions are met, which means the code for the Run method is not executed if a condition is not met. All the conditions are enumerated in the SystemConditionType enum: ■ ■ InternetAvailable An Internet connection must be available. ■ ■ InternetNotAvailable An Internet connection must be unavailable. ■ ■ SessionConnected The session must be connected. ■ ■ SessionDisconnected The session must be disconnected. ■ ■ UserNotPresent The user must be away. ■ ■ UserPresent The user must be present. The maintenance trigger can schedule a background task as frequently as every 15 min- utes if the device is plugged in to an AC power source. It is not fired if the device is running on batteries. System triggers and maintenance triggers run for every application that registers them (and declares them in the application manifest). In addition, an application that leverages the lock screen–capable feature of the Windows Runtime can also register background tasks for other events. An application can be placed on the lock screen to show important information to the user: The user can choose the application he or she wants on the lock screen (up to seven in the first release of Windows 8). You can use the following triggers to run code for an app on the lock screen: ■ ■ PushNotificationTrigger Raised when a notification arrives on the Windows Push Notifications Service channel. ■ ■ TimeTrigger Raised at scheduled intervals. The app can schedule a task to run as frequently as every 15 minutes. ■ ■ ControlChannelTrigger Raised when there are incoming messages on the control channel for apps that keep connections alive.
  • 33. Objective 1.2: Consume background tasks CHAPTER 1 11 It is important to note that the user must place the application on the lock screen before the application can use triggers. The application can ask the user to access the lock screen by calling the RequestAccessAsync method. The system presents a dialog box to the user, asking for her or his permission to use the lock screen. The following triggers are usable only by lock screen–capable applications: ■ ■ ControlChannelReset The control channel is reset. ■ ■ SessionConnected The session is connected. ■ ■ UserAway The user must be away. ■ ■ UserPresent The user must be present. In addition, when a lock screen–capable application is placed on the lock screen or re- moved from it, the following system events are triggered: ■ ■ LockScreenApplicationAdded The application is added to the lock screen. ■ ■ LockScreenApplicationRemoved The application is removed from the lock. A time-triggered task can be scheduled to run either once or periodically; this kind of task is useful to update the application tile or badge with some kind of information. For example, a weather app updates the temperature to show the most recent one in the application tile, whereas a finance application refreshes the quote for the preferred stock. The code to define a time trigger is similar to the code for a maintenance trigger: TimeTrigger taskTrigger = new TimeTrigger(60, true); The first parameter (freshnessTime) is expressed in minutes, and the second parameter (oneShot) indicates whether the trigger will fire only once or at every freshnessTime occurrence. The Windows Runtime has an internal timer that runs tasks every 15 minutes. If the freshnessTime is set to 15 minutes and oneShot is set to false, the task will run every 15 minutes, starting between the time the task is registered and the 15 minutes ahead. If the freshnessTime is set to 15 minutes and oneShot is set to true, the task will run 15 minutes from the registration time. EXAM TIP You cannot set the freshnessTime to a value less than 15 minutes. An exception occurs if you try to do this. Time trigger supports all the conditions in the SystemConditionType enum presented ear- lier in this section. Progressing through and completing background tasks If an application needs to know the result of the task execution, it can provide a callback for the OnCompleted event. The callback receives the instance of the BackgroundTaskRegistration used to register the task and the corresponding event arguments.
  • 34. 12 CHAPTER 1 Develop Windows Store apps The following code creates a task and registers an event handler for the completion event: var builder = new BackgroundTaskBuilder(); builder.Name = taskName; builder.TaskEntryPoint = "BikeGPS.BikePositionUpdateBackgroundTask"; builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false)); builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable)); BackgroundTaskRegistration taskRegistration = builder.Register(); taskRegistration.Completed += taskRegistration_Completed; A simple event handler, receiving the BackgroundTaskRegistration as the sender, can show something to the user as in the following code, or it can update the application tile with some information: void taskRegistration_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args) { if (sender.Name == "BikeGPS.BikePositionUpdateBackgroundTask") { var dialog = new MessageDialog("Task BikePositionUpdateBackgroundTask completed."); dialog.ShowAsync(); } } EXAM TIP A background task can be executed when the application is suspended or even terminated. The OnCompleted event callback will be fired when the application is resumed from the operating system or the user launches it again. If the application is in the foreground, the event callback is fired immediately. A well-written application needs to check errors in the task execution. Because the task is already completed, you need to see whether the result is available or whether some- thing went wrong. To do that, the code can call the CheckResult method of the received BackgroundTaskCompletedEventArgs. This method throws the exception that occurred during task execution, if any; otherwise, it simply returns a void. Listing 1-4 shows the correct way to handle an exception inside a single task. LISTING 1-4 Completed event with exception handling void taskRegistration_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args) { if (sender.Name == "BikeGPS.BikePositionUpdateBackgroundTask") { try
  • 35. Objective 1.2: Consume background tasks CHAPTER 1 13 { args.CheckResult(); var dialog = new MessageDialog( "Task BikePositionUpdateBackgroundTask completed successfully"); dialog.ShowAsync(); } catch (Exception ex) { var dialog = new MessageDialog( "Task BikePositionUpdateBackgroundTask Errors " + ex.Message); dialog.ShowAsync(); } } } Right after the check for the task name, exposed by the Name property of the Back- groundTaskRegistration received in the event handler parameter, use a try/catch block to intercept the exception fired by the CheckResult method, if any. In the sample presented in Listing 1-4, we simply create a dialog box to show the correct completion or the exception thrown by the background task execution. Another useful event a background task exposes is the OnProgress event that, as the name implies, can track the progress of an activity. The event handler can update the user interface that is displayed when the application is resumed, or update the tile or the badge with the progress (such as the percent completed) of the job. The code in Listing 1-5 is an example of a progress event handler that updates application titles manually: LISTING 1-5 Sample progress event handler that updates the application tile void taskRegistration_Progress(BackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs args) { string tileXmlString = "<tile>" + "<visual>" + "<binding template='TileWideText03'>" + "<text id='1'>" + args.Progress.ToString() + "</text>" + "</binding>" + "<binding template='TileSquareText04'>" + "<text id='1'>" + args.Progress.ToString() + "</text>" + "</binding>" + "</visual>" + "</tile>"; var tileXml = new Windows.Data.Xml.Dom.XmlDocument(); tileXml.LoadXml(tileXmlString); var tile = new Windows.UI.Notifications.TileNotification(tileXml); Windows.UI.Notifications.TileUpdateManager.CreateTileUpdaterForApplication() .Update(tile); }
  • 36. 14 CHAPTER 1 Develop Windows Store apps The code in Listing 1-5 builds the XML document using the provided template and creates a TileNotification with a single value representing the process percentage. Then the code uses the CreateTileUpdaterForApplication method of the TileUpdateManager class to update the live tile. The progress value can be assigned in the Run method using the Progress property of the IBackgroundTaskInstance instance that represents the task. This instance is received directly as the parameter of the Run method. The following code shows a simple example of progress assignment: public sealed class BikePositionUpdateBackgroundTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { // Update the GPS coordinates // First operation taskInstance.Progress = 10; // Second operation taskInstance.Progress = 20; /// .... } } Understanding task constraints As stated, background tasks have to be lightweight so they can provide the best user experi- ence with foreground apps and battery life. The runtime enforces this behavior by applying resource constraints to the task: ■ ■ CPU for application not on the lock screen The CPU is limited to 1 second. A task can run every 2 hours at a minimum. For application on the lock screen, the system will execute a task for 2 seconds with a 15-minute maximum interval. ■ ■ Network access When running on batteries, tasks have network usage limits cal- culated based on the amount of energy used by the network card. This number can be very different from device to device based on their hardware. For example, with a throughput of 10 megabits per second (Mbps), an app on the lock screen can consume about 450 megabytes (MB) per day, whereas an app that is not on the lock screen can consume about 75 MB per day. MORE INFO TASK CONSTRAINTS Refer to the MSDN documentation at http://msdn.microsoft.com/en-us/library/win- dows/apps/xaml/hh977056.aspx for updated information on background task resource constraints.
  • 37. Objective 1.2: Consume background tasks CHAPTER 1 15 To prevent resource quotas from interfering with real-time communication apps, tasks using ControlChannelTrigger and PushNotificationTrigger receive a guaranteed resource quota (CPU/network) for every running task. The resource quotas and network data usage constraints remain constant for these background tasks rather than varying according to the power usage of the network interface. Because the system handles constraints automatically, your app does not have to request resource quotas for ControlChannelTrigger and PushNotificationTrigger background tasks. The Windows Runtime treats these tasks as “critical” background tasks. If a task exceeds these quotas, it is suspended by the runtime. You can check for suspen- sion by inspecting the SuspendedCount property of the task instance in the Run method, choosing to stop or abort the task if the counter is too high. The following code illustrates how to check for suspension: public sealed class BikePositionUpdateBackgroundTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { // Update the GPS coordinates if (taskInstance.SuspendedCount > 5) return; } } Cancelling a task When a task is executing, it cannot be stopped unless the task recognizes a cancellation re- quest. A task can also report cancellation to the application using the persistent storage. The Run method has to check for cancellation requests. The easiest way is to declare a Boolean variable in the class and set it to true if the system has cancelled the task. This vari- able will be set to true in the OnCanceled event handler and checked during the execution of the Run method to exit it. Listing 1-6 shows the simplest complete class to check for cancellation. LISTING 1-6 Task cancellation check public sealed class BikePositionUpdateBackgroundTask : IBackgroundTask { volatile bool _cancelRequested = false; public void Run(IBackgroundTaskInstance taskInstance) { taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled); // Update the GPS coordinates // First operation taskInstance.Progress = 10;
  • 38. 16 CHAPTER 1 Develop Windows Store apps if (_cancelRequested == true) return; // Second operation taskInstance.Progress = 20; /// .... } private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) { // you can use sender.Task.Name to identity the task _cancelRequested = true; } } In the Run method, the first line of code sets the event handler for the Canceled event to the OnCanceled method. Then it does its job setting the progress and testing the value of the variable to stop working (return or break, in case of a loop). The OnCanceled method sets the _cancelRequested variable to true. To recap, the system will call the Canceled event handler (OnCanceled) during a cancellation. The code sets the variable tested in the Run method to stop working on the task. If the task wants to communicate some data to the application, it can use local persistent storage as a place to store some data the application can interpret. For example, the Run method can save the status in a LocalSettings key to let the application know if the task has been successfully completed or cancelled. The application can then check this information in the Completed event for the task. Listing 1-7 shows the revised Run method. LISTING 1-7 Task cancellation using local settings to communicate information to the app public void Run(IBackgroundTaskInstance taskInstance) { taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled); // Update the GPS coordinates // First operation taskInstance.Progress = 10; if (_cancelRequested == true) { ApplicationData.Current.LocalSettings.Values["status"] = "canceled"; return; } // Second operation taskInstance.Progress = 20;
  • 39. Objective 1.2: Consume background tasks CHAPTER 1 17 /// .... /// ApplicationData.Current.LocalSettings.Values["status"] = "completed"; } Before “stopping” the code in the Run method, the code sets the status value in the LocalSettings; that is, the persistent storage dedicated to the application, to canceled. If the task completes its work, the value will be completed. The code in Listing 1-8 inspects the LocalSettings value to determine the task outcome. This is a revised version of the taskRegistration_Completed event handler used in a previous sample. LISTING 1-8 Task completed event handler with task outcome check void taskRegistration_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args) { if (sender.Name == "BikeGPS.BikePositionUpdateBackgroundTask") { try { args.CheckResult(); var status = ApplicationData.Current.LocalSettings.Values["status"]; MessageDialog dialog; if(status == "canceled") dialog = new MessageDialog( "Task BikePositionUpdateBackgroundTask canceled"); else dialog = new MessageDialog( "Task BikePositionUpdateBackgroundTask completed"); dialog.ShowAsync(); } catch (Exception ex) { var dialog = new MessageDialog( "Task BikePositionUpdateBackgroundTask Errors " + ex.Message); dialog.ShowAsync(); } } } The registered background task persists in the local system and is independent from the application version.
  • 40. 18 CHAPTER 1 Develop Windows Store apps Updating a background task Tasks “survive” application updates. If a newer version of the application needs to update a task or modify its behavior, it can register the background task with the ServicingComplete trigger; this way the app is notified when the application is updated and unregisters tasks that are no longer valid. Listing 1-9 shows a task that unregisters the previous version and registers the new one. LISTING 1-9 Using the ServicingComplete task to update a previous version of a task using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.ApplicationModel.Background; using Windows.Storage; namespace BikeGPS { public sealed class ServicingCompleteTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { // Look for Task v1 var task = FindTask("BikeGPS.BikePositionUpdateBackgroundTask"); if (task != null) { task.Unregister(true); } var builder = new BackgroundTaskBuilder(); builder.Name = task.Name; builder.TaskEntryPoint = "BikeGPS.BikePositionUpdateBackgroundTask"; builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false)); builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable)); BackgroundTaskRegistration taskRegistration = builder.Register(); }
  • 41. Objective 1.2: Consume background tasks CHAPTER 1 19 public static BackgroundTaskRegistration FindTask(string taskName) { foreach (var task in BackgroundTaskRegistration.AllTasks) { if (task.Value.Name == taskName) { return (BackgroundTaskRegistration)(task.Value); } } return null; } } } The parameter of the Unregister method set to true forces task cancellation, if implemented, for the background task. The FindTask method is simply a helper you can use throughout the code to find a task by name in the list of already registered tasks and return it to the caller. The last thing to do is use a ServicingComplete task in the application code to register this “system” task as other tasks using the ServicingComplete system trigger type: SystemTrigger servicingCompleteTrigger = new SystemTrigger(SystemTriggerType.ServicingComplete, false); Debugging tasks Debugging a background task can be a challenging job if you try to use a manual tracing method. A timer or a maintenance-triggered task can be executed in the next 15 minutes based on the internal interval, so debugging manually is not so effective. To ease this job, the Visual Studio background task integrated debugger simplifies the task activation. Make sure that the Windows Store application references the background task project and the latter is configured as WinMD File. In addition, the project has to declare the back- ground task in the application manifest. Figure 1-2 shows the complete solution with the BikeBackgroundTask project referenced by the main application, and the project property showing the output type set to Windows Runtime Component (also referred to as the WinMD library or file).
  • 42. 20 CHAPTER 1 Develop Windows Store apps FIGURE 1-2 Solution structure and output type for a background task Place a breakpoint in the Run method or use the Debug class to write some values in the output window. Start the project at least one time to register the task in the system and then use the Debug Location toolbar in Visual Studio to activate the background task. The toolbar can show only registered tasks waiting for the trigger. The toolbar can be activated using the View command on the Toolbars menu. Figure 1-3 shows the background registration code and the Debug Location toolbar. FIGURE 1-3 Visual Studio “hidden” Debug Location toolbar to start tasks
  • 43. Objective 1.2: Consume background tasks CHAPTER 1 21 Figure 1-4 shows the debugger inside the Run method. FIGURE 1-4 Debugging tasks activated directly from Visual Studio Understanding task usage Every application has to pass the verification process during application submission to the Windows Store. Be sure to double-check the code for background tasks using the following points as guidance: ■ ■ Do not exceed the CPU and network quotas in your background tasks. Tasks have to be lightweight to save battery power and provide a better user experience for the ap- plication in the foreground.
  • 44. 22 CHAPTER 1 Develop Windows Store apps ■ ■ The application should get the list of registered background tasks, register for progress and completion handlers, and handle these events in the correct manner. The classes should also report progress, cancellation, and completion. ■ ■ If the Run method uses asynchronous code, make sure the code uses deferrals to avoid premature termination of the method before completion. Without a deferral, the Windows Runtime thinks that your code has finished its work and can terminate the thread. Request a deferral, use the async/await pattern to complete the asynchronous call, and close the deferral after the await keyword. ■ ■ Declare each background task and every trigger associated with it in the application manifest. Otherwise, the app cannot register the task at runtime. ■ ■ Use the ServicingComplete trigger to prepare your application for updating. ■ ■ If you use the lock screen–capable feature, remember that only seven apps can be placed on the lock screen, and the user can choose the application she wants on it at any time. Furthermore, only one app can have a wide tile. The application can provide a good user experience by requesting lock screen access using the RequestAccessAsync method. Be sure the application can work without permission to use the lock screen because the user can deny access to it or remove the permission later. ■ ■ Use tiles and badges to provide visual clues to the user and use the notification mecha- nism in the task to notify third parties. Do not use any other UI elements in the run method. ■ ■ Use persistent storage as ApplicationData to share data between the background task and the application. Never rely on user interaction in the task. ■ ■ Write background tasks that are short-lived. Transferring data in the background Some applications need to download or upload a resource from the web. Because of the ap- plication life-cycle management of the Windows Runtime, if you begin to download a file and then the user switches to another application, the first app can be suspended; the file cannot be downloaded during suspension because the system gives no thread and no I/O slot to a suspended app. If the user switches back to the application again, the download operation can continue but will take more time to be completed. Moreover, if the system needs resourc- es, it can terminate the application. The download is then terminated together with the app. The BackgroundTransfer namespace provides classes to avoid these problems. It can be used to enhance the application with file upload and download features that run in the back- ground during suspension. It supports HTTP and HTTPS for download and upload operations, and File Transfer Protocol (FTP) for download-only operations. This class is aimed at large file uploads and downloads.
  • 45. Objective 1.2: Consume background tasks CHAPTER 1 23 The process started by this class runs separately from the Windows Store app and can be used to work with resources such as files, music, large images, and videos. During the operation, if the runtime chooses to put the application in the suspended state, the capability provided by the Background Transfer APIs continues to work in the background. NOTE BACKGROUND TRANSFER API Background Transfer APIs work for small resources (a few kilobytes), but Microsoft sug- gests using the traditional HttpClient class for these kind of files. The process to create a file download operation involves the BackgroundDownloader class: The settings and initialization parameters provide different ways to customize and start the download operation. The same applies for upload operations using the BackgroundUploader class. You can call multiple download/upload operations using these classes from the same application because the Windows Runtime handles each operation individually. During the operation, the application can receive events to update the UI (if the applica- tion is still in the foreground), and you can provide a way to stop, pause, resume, or cancel the operation. You can also read the data during the transfer operation. These operations support credentials, cookies, and the use of HTTP headers, so you can use them to download files from a secured location or provide a custom header to a custom server-side HTTP handler. The operations are managed by the Windows Runtime, promoting smart usage of power and bandwidth. They are also independent from sudden network status changes because they intelligently leverage connectivity and carry data-plan status information provided by the Connectivity namespace. The application can provide a cost-based policy for each operation using the BackgroundTranferCostPolicy. For example, you can provide a cost policy to pause the task automatically when the machine is using a metered network and resume it if the user comes back to an “open” connection. The application has to do nothing to manage these situations; it is sufficient to provide the policy to the background operation. To enable a transfer operation in background, first enable the network in the Package.appx- manifest file using one of the provided options in the App Manifest Designer. You must use one of the following capabilities: ■ ■ Internet (Client) The app has outbound access to the Internet and networks in pub- lic areas, such as coffee shops, airports, and parks. ■ ■ Internet (Client & Server) The app can receive inbound requests and make out- bound requests in public areas. ■ ■ Private Networks The app can receive inbound requests and make outbound re- quests in trusted places, such as at home and work. Figure 1-5 shows the designer with the application capabilities needed for background data transferring.
  • 46. 24 CHAPTER 1 Develop Windows Store apps FIGURE 1-5 Capabilities for background transferring Then you can start writing code to download a file in the local storage folder. The code excerpt in Listing 1-10 starts downloading the session1.wmv file in the Videos Library folder. LISTING 1-10 Code to activate a background transfer private async void Download_Click(object sender, RoutedEventArgs e) { try { var fileName = "session1.wmv"; Uri source = new Uri("http://videos.devleap.com/" + fileName); var targetFile = await KnownFolders.VideosLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName); var downloader = new BackgroundDownloader(); var downloadOperation = downloader.CreateDownload(source, targetFile); await downloadOperation.StartAsync(); LogOperation(String.Format("Current Download {0} to {1}, {2}", source.AbsoluteUri, targetFile.Name, downloadOperation.Guid));
  • 47. Objective 1.2: Consume background tasks CHAPTER 1 25 } catch (Exception ex) { LogOperation("Download Error", ex); } } The first line of code sets a local variable representing the file name to download and uses it to create the URI for the source file. Then the CreateFileAsync method creates a file in the user’s Videos library represented by the KnownFolders.VideosLibrary storage folder using the async/await pattern. The BackgroundDownloader class exposes a CreateDownload method to begin the down- load operation: It returns a DownloadOperation class representing the current operation. The BackgroundDownloader class exposes the StartAsync method to start the operation. The main properties of this class are: ■ ■ Guid Represents the autogenerated unique id for the download operation you can use in the code to create a log for every download operation ■ ■ RequestedUri (read-only) Represents the URI from which to download the file ■ ■ ResultFile Returns the IStorageFile object provided by the caller when creating the download operation The BackgroundDownloader class also exposes the Pause and the Resume method as well as the CostPolicy property to use during the background operation. To track the progress of the download operation, you can use the provided StartAsync method, transforming the result in a Task and passing the progress callback using an instance of the System.Progress<T> class. Listing 1-11 shows the revised sample. LISTING 1-11 Activating a background transfer and providing progress information private async void Download_Click(object sender, RoutedEventArgs e) { try { var fileName = "session1.wmv"; Uri source = new Uri("http://video.devleap.com/" + fileName); var targetFile = await KnownFolders.VideosLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName); var downloader = new BackgroundDownloader(); var downloadOperation = downloader.CreateDownload(source, targetFile); Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
  • 48. 26 CHAPTER 1 Develop Windows Store apps await downloadOperation.StartAsync().AsTask(progressCallback); LogOperation(String.Format("Current Download {0} to {1}, {2}", source.AbsoluteUri, targetFile.Name, downloadOperation.Guid)); } catch (Exception ex) { LogOperation("Download Error", ex); } } private void DownloadProgress(DownloadOperation downloadOperation) { LogOperation(String.Format("Downloading {0} to {1}, {2}", downloadOperation.RequestedUri, downloadOperation.Progress , downloadOperation.Guid) } In the preceding code, right after the creation of the download operation, the StartAsync method returns the IAsyncOperationWithProgress<DownloadOperation, DownloadOperation> interface that is transformed in a Task using the AsTask method; this method receives the Progress<T> instance that represents the callback. This way, the callback can receive the DownloadOperation class and can use the Guid, RequestedUri, or ResultFile properties to track the progress or to log them (or display them if the application is in the foreground) as appropriate for the application. The BackgroundDownloader tracks and manages all the current download operations; you can enumerate them using the GetCurrentDownloadAsync method. Because the system can terminate the application, it is important to reattach the progress and completion event handler during the next launch operation performed by the user. Use the following code as a reference in the application launch: IReadOnlyList<DownloadOperation> downloads = await BackgroundDownloader.GetCurrentDownloadsAsync(); if (downloads.Count > 0) { List<Task> tasks = new List<Task>(); foreach (DownloadOperation download in downloads) { Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress); await download.AttachAsync().AsTask(progressCallback); } }
  • 49. Objective 1.2: Consume background tasks CHAPTER 1 27 This method iterates through all the current download operations and reattaches the progress callback to each of them using the AttachAsync method. The method returns an asynchronous operation that can be used to monitor progress and completion of the at- tached download. Calling this method enables an app to reattach download operations that were started in a previous app instance. Finally, you should address the time-outs enforced by the system. When establishing a new connection for a transfer, the connection request is aborted if it is not established within five minutes. After establishing a connection, an HTTP request message that has not received a response within two minutes is aborted. The same concepts apply to resource upload. The BackgroundUploader class works in a similar way as the BackgroundDownloader class. It is designed for long-term operations on resources such as files, images, music, and videos. As mentioned for download operations, small resources can be uploaded using the traditional HttpClient class. You can use CreateUploadAsync to create an asynchronous operation that, on completion, returns an UploadOperation. There are three overloads for this method. The “BackgroundUp- loader class” page in the MSDN official documentation provides these descriptions: ■ ■ CreateUploadAsync(Uri, IIterable(BackgroundTransferContentPart)) Returns an asynchronous operation that, on completion, returns an UploadOperation with the specified URI and one or more BackgroundTransferContentPart objects ■ ■ CreateUploadAsync(Uri, IIterable(BackgroundTransferContentPart), String) Returns an asynchronous operation that, on completion, returns an UploadOperation with the specified URI, one or more BackgroundTransferContentPart objects, and the multipart subtype ■ ■ CreateUploadAsync(Uri, IIterable(BackgroundTransferContentPart), String, String) Returns an asynchronous operation that, on completion, re- turns an UploadOperation with the specified URI, multipart subtype, one or more BackgroundTransferContentPart objects, and the delimiter boundary value used to separate each part Alternatively, you can use the more specific CreateUploadFromStreamAsync that returns an asynchronous operation that, on completion, returns the UploadOperation with the specified URI and the source stream. This is the method definition: public IAsyncOperation<UploadOperation> CreateUploadFromStreamAsync( Uri uri, IInputStream sourceStream )
  • 50. 28 CHAPTER 1 Develop Windows Store apps As for the downloader classes, this class exposes the ProxyCredential property to provide authentication to the proxy and ServerCredential to authenticate the operation with the tar- get server. You can use the SetRequestHeader method to specify HTTP header key/value pairs. Keeping communication channels open For applications that need to work in the background, such as VoIP, instant messaging, and email, the new Windows Store application model provides an always-connected experience for the end user. In practice, an application that depends on a long-running network connec- tion to a remote server can still work even when the Windows Runtime suspends the appli- cation. As you learned, a background task enables the application to perform some kind of work in the background when the application is suspended. Keeping a communication channel open is required for an application that sends data to or receives data from a remote endpoint. It is also required for long-running server processes to receive and process any incoming requests from the outside. Typically, this kind of application sits behind a proxy, a firewall, or a Network Address Translation (NAT) device. This hardware component preserves the connection if the endpoints continue to exchange data: if there is no traffic for some time (it can be few seconds or min- utes) these devices close the connection. To ensure that the connection is not lost and remains open between server and client endpoints, the application can be configured to use some kind of keep-alive connection (that is, a message is sent on the network at periodic intervals) so that the connection lifetime is prolonged. These messages can be easily sent in previous versions of Windows because the applica- tion stays in the Running state until the user decides to close (or terminate) it. In this scenario, keep-alive messages can be sent without any problems. The new Windows 8 application life-cycle management, on the contrary, does not guarantee that packets are delivered to a suspended app. Moreover, incoming network connections can be dropped and no new traffic is sent to a suspended app; these behaviors have an impact on the network devices that cut the connection between apps because they become “idle” from a network perspective. To be always connected, a Windows Store app needs to be a lock screen–capable applica- tion. Only applications that use one or more background tasks can be lock screen apps. An app on the lock screen can do the following: ■ ■ Run code when a time trigger occurs. ■ ■ Run code when a new user session is started. ■ ■ Receive a raw push notification from Windows Push Notification Service and run code when a notification is received. ■ ■ Maintain a persistent transport connection in the background to remote services or endpoints, and run code when a new packet is received or a keep-alive packet needs to be sent using a network trigger.
  • 51. Objective 1.2: Consume background tasks CHAPTER 1 29 Remember that a user can have a maximum of seven lock screen apps at any given time. A user can also add or remove an app from the lock screen at any time. Windows Push Notification Service (WNS) is a cloud service hosted by Microsoft for Win- dows 8. Windows Store apps can use WNS to receive notifications that can run code, update a live tile, or raise an on-screen notification. To use WNS, the local computer must be connect- ed to the Internet so that the WNS service can communicate with it. A Windows Store app in the foreground can use WNS to update live tiles, raise notifications to the user, or update badges. Apps do not need to be on the lock screen to use WNS. You should consider using WNS in your app if it must run code in response to a push notification. MORE INFO WINDOWS PUSH NOTIFICATION SERVICE (WNS) For a complete discussion of WNS, see Chapter 3, “Program user interaction.” The ControlChannelTrigger class in the System.Net.Sockets namespace implements the trig- ger for applications that must maintain a persistent connection to a remote endpoint: Use this feature if the application cannot use WNS. For example, an email application that uses some POP3 servers cannot be modified to use a push notification because the server does not implement WNS and does not send messages to POP3 clients. The ControlChannelTrigger can be used by instances of one of the following classes: MessageWebSocket, StreamWebSocket, StreamSocket, HttpClient, HttpClientHandler, and related classes in the System.Net.Http namespace in .NET Framework 4.5. The IXML- HTTPRequest2, an extension of the classic XMLHttpRequest, can also be used to activate a ControlChannelTrigger. The main benefits of using a network trigger are compatibility with existing client/server protocols and the guarantee of message delivery. The drawbacks are a little more complex in respect to WNS, and the maximum number of triggers an app can use is five in the current version of the Windows Runtime. EXAM TIP An application written in JavaScript cannot use a ControlChannelTrigger if it uses other background tasks. An application that uses a network trigger needs to request the lock screen permission. This feature supports two different resources for a trigger: ■ ■ Hardware slot The application can use background notification even when the de- vice is in low-power mode or standby (connected to a plug). ■ ■ Software slot The application cannot use network notification when not in low- power mode or standby (connected to a plug).
  • 52. 30 CHAPTER 1 Develop Windows Store apps This resource capability provides a way for your app to be triggered by an incoming noti- fication even if the device is in low-power mode. By default, a software slot is selected if the developer does not specify an option. A software slot enables your app to be triggered when the system is not in connected standby. This is the default on most computers. There are two trigger types: ■ ■ Push notification network trigger Enables a Windows Store app to process incom- ing network packets on an already established TCP socket, even if the application is suspended. This socket, which represents the control channel that exists between the application and a remote endpoint, is created by the application to trigger a back- ground task when a network packet is received by the application. In practice, the control channel is a persistent TCP/IP connection maintained alive by the Windows Runtime even if the application is sent in the background and suspended. ■ ■ Keep-alive network trigger Enables a suspended application to send keep-alive packets to a remote service or endpoint. To avoid connection cutting, the keep-alive packets tell the network device that a connection is still in use. Before using a network trigger, the application has to be a lock screen app. You need to declare application capability and then call the appropriate method to ask the user for per- mission to place the application on the lock screen. NOTE LOCK SCREEN REMOVAL You also have to handle a situation in which the user removes the application from the lock screen. To register an application for the lock screen, ensure that the application has a WideLogo definition in the application manifest on the DefaultTile element: <DefaultTile ShowName="allLogos" WideLogo="AssetswideLogo.png" /> Add a LockScreen element that represents the application icon on the lock screen inside the VisualElements node in the application manifest: <LockScreen Notification="badge" BadgeLogo="AssetsbadgeLogo.png" /> You can use the App Manifest Designer, shown in Figure 1-6, to set these properties. The Wide Logo and the Badge Logo reference the relative images, and the Lock Screen Notifica- tions element is set to Badge.
  • 53. Objective 1.2: Consume background tasks CHAPTER 1 31 FIGURE 1-6 Badge and wide logo definition Declare the extensions to use a background task, and define the executable file that contains the task and the name of the class implementing the entry point for the task. The task has to be a controlChannel background task type. For this kind of task, the executable
  • 54. 32 CHAPTER 1 Develop Windows Store apps file is the application. Apps using the ControlChannelTrigger rely on in-process activation for background task. The following code declares the background task: Sample of XML code <Extensions> <Extension Category="windows.backgroundTasks" Executable="$targetnametoken$.exe" EntryPoint="ControlChannelTriggerTask.ReceiveTask"> <BackgroundTasks> <Task Type="controlChannel" /> </BackgroundTasks> </Extension> </Extensions> The dynamic-link library (DLL) or the executable file that implements the task for keep- alive or push notifications must be linked as a WinRT component (WinMD library). You can also use the App Manifest Designer to set these extensions in an easier way, as shown in Figure 1-7. FIGURE 1-7 Background tasks app settings The next step is to ask the user for permission to become a lock screen application using the RequestAccessAsync method of the BackgroundExecutionManager class of the Windows. ApplicationModel.Background namespace. See Listing 1-12. The call to this method presents a dialog box to the user to approve the request.
  • 55. Another Random Document on Scribd Without Any Related Topics
  • 56. follow him by the plain trail he'll leave. We'll come to our breakfast in less than ten minutes." Phil soon saw that Breakstone was right. The trail on the other side of the salt spring was plain and red, and presently they found the great stag in a thicket, lying upon his side, stone dead, Bill Breakstone was an adept at cleaning and dressing, and soon the ugly work was over. They always carried matches, and Phil quickly lighted a fire of dry sticks that burned up rapidly and that soon made a fine heap of glowing coals. "Now," said Breakstone, "we'll cook and eat, then we'll cook and eat again, then we'll cook and eat once more." "And I don't care very much whether Comanches heard the rifle shot or not," said Phil. "It seems to me that when I eat as much as I want I can whip the whole Comanche nation." "I feel that way, too," said Bill Breakstone, "but the Comanches didn't hear. I know it in my bones. Didn't I tell you about that streak of luck? Luck's coming our way now, and the streak will last for awhile." They cut long twigs, sharpened them at the ends, and fried over the coals strips of the deer, which gave out such a rich aroma as they sputtered that the two could scarcely restrain themselves. Yet they did it, they remained white men and gentlemen, and did not guzzle. "Phil," said Bill, before he took a single bite, "I remember about that dinner in New Orleans you were talking of so long ago. I remember about those beautiful oysters, those splendid fish from the gulf, the gorgeous Virginia ham, the magnificent Louisiana turkey; yes, I remember all those magnificent fripperies and
  • 57. frummeries, but it seems to me if they were all set down before us, spread on a service of golden plate, they wouldn't be finer than what is now awaiting us." "Bill," said Phil with deep emphasis and unction, "you never spoke truer words in your life." "Then lay on, Macduff, and the first who cries 'hold, enough'-- well, he won't be much of a trencherman." They fell to. They did not eat greedily, but they ate long and perseveringly. Strip after strip was fried over the coals, gave out its savory odor, and disappeared. Phil occasionally replenished the fire, adding to the bed of coals, but keeping down the smoke. Bill, stretching his long body on the ground and then propping himself up on his elbow, concluded that it was a beautiful world. "Didn't I tell you our luck would hold for awhile?" he repeated. "Since we got into the woods, things have come easy. A good bed put itself right in our way, then a deer walked up and asked to be eaten. "The deer It was here. One shot-- In our pot. "We haven't any pot, but you can use things in a metaphorical sense in order to get your rhyme. That's what poetry is for." "I'm beginning to feel satiated," said Phil.
  • 58. "'Satiated' is a good word," said Bill Breakstone, "but it isn't used much on the plains. Still, I'm beginning to feel that way myself, too, and I think we'd better begin to consider the future, which is always so much bigger than the present." "We must find our horses." "Of course, and after that we must find the train, which will be our chief problem. It may be where we left it or it may have gone on, thinking that we had been killed by some outlying party of Comanches. But I don't believe Middleton and Arenberg would move without us. They may now be somewhere in these woods looking for us." "Can you figure out the direction of the valley in which we left our horses?" Breakstone studied the sun attentively. "It's southeast from here," he replied, "and I fancy it's not more than three or four miles. Two likely lads like you and me ought to find it pretty soon, and, nine chances out of ten, the horses will be there. We'll take some of the best portions of the deer with us, and start at once." They chose the choicest pieces of the meat and started, now strong of body and light of heart. Phil's own judgment about the direction agreed with Breakstone's, and in less than an hour they saw familiar ground. "I'm a good prophet to-day," said Breakstone. "I've got the gift for a few hours at least. I predicted truly about the deer, and now I am going to predict truly about the horses. We'll have them by the bridle inside of half an hour."
  • 59. In fifteen minutes they were in the little valley, in three minutes they found the horses grazing peacefully, and in two more minutes they caught them. "We've done the work and with ten minutes to spare," said Bill Breakstone, triumphantly, "and now, Phil, another wonderful change in our fortunes has come. If a camel is the ship of the desert, then a horse is the boat of the plains, the long boat, the jolly boat, the row boat, and all the rest of them. Now for the wagon train!" "Now for the wagon train!" repeated Phil. CHAPTER VIII NEW ENEMIES The two were in splendid spirits. They had escaped great dangers, and they were on horseback once more. It is true, they were somewhat short on armament, but Breakstone took Phil's pistol, while the latter kept the rifle, and they were confident that they could find game enough on the plains until they overtook the wagon train. The horses themselves seemed glad of the companionship of their old masters, and went forward readily and at an easy pace through the woods. They soon found the path by which they had come, and followed it until they crossed the river and reached the site of the camp. But the trail toward the plain lay before them broad and easy. "They can't have gone long," said Breakstone. "They may have thought that we were merely loitering behind for some purpose of
  • 60. our own and would soon overtake them. A whole train isn't going to linger about for two fellows well mounted and well armed who are supposed to know how to take care of themselves. But, Sir Philip of the Youthful Countenance, I don't think that Middleton and Arenberg would go ahead without us." "Neither do I," said Phil with emphasis. "I as good as know that they're looking for us in these woods, and we've got to stay behind and find them, taking the risk of Comanches." "Wherein I do heartily agree with you, and I'm going to take a chance right now. It is likely that the two, after fruitless searches for us, would return here at intervals, and, in a region like this, the sound of a shot will travel far. Fire the rifle, Phil, and it may bring them. It's often used as a signal. If it brings the Comanches instead, we're on our horses, and they're strong and swift." Phil fired a shot, but there was no response. He waited half an hour and fired a second time, with the same result. After another half hour, the third shot was fired, and, four or five minutes later, Breakstone announced that he heard the tread of hoofs. It was a faint, distant sound, but Phil, too, heard it, and he was confident that it was made by hoofs. The two looked at each other, and each read the question in the other's eye. Who were coming in reply to the call of that third rifle shot, red men or white? "We'll just draw back a little behind this clump of bushes," said Breakstone. "We can see a long way through their tops, and not be seen until the riders come very close. Then, if the visitors to this Forest of Arden of ours, Sir Philip, are not those whom we wish to see, it's up and away with us."
  • 61. They waited in strained eagerness. The sounds grew louder. It was certain, moreover, that the riders were coming straight toward the point at which the rifle had been fired. "Judging from the hoof beats, how many would you say they are?" asked Phil. "Not many. Maybe three or four, certainly not more. But I'm hoping that it's two, neither more nor less." On came the horsemen, the hoofbeats steadily growing louder. Phil rose in his stirrups and gained a further view. He saw the top of a soft hat and then the top of another. In a half minute the faces beneath came into view. He knew them both, and he uttered a cry of joy. "Middleton and Arenberg!" he exclaimed. "Here they come!" "Our luck still holds good," said Bill Breakstone. He and Phil galloped from behind the bushes and shouted as warm a welcome as men ever had. They received one equally warm in return, as Middleton and the German urged their horses forward. Then there was a mighty shaking of hands and mutual congratulations. "The train left yesterday morning," said Middleton, "but we couldn't give you up. We scouted all the way across the forest and saw the Comanches on the other side. There was nothing to indicate anything unusual among them, such as a sacrifice of prisoners, and we hoped that if you had been taken by them you had escaped, and we came back here to see, knowing that if you were able you would return to this place. We were right in one part of our guess, because here you are." "And mighty glad we are to be here," said Bill Breakstone, "and I want to say to you that I, Bill Breakstone, who may not be of so
  • 62. much importance to the world, but who is of vast importance to himself, would not be here at all, or anywhere else, for that matter, if it were not for this valiant and skillful youth, Sir Philip Bedford, Knight of the Texas plains." "Stop, Bill," exclaimed Phil blushing. "Don't talk that way." "Talk that way! Of course I will! And I'll pile it up, too! And after I pile it up and keep on piling it up, it won't be the whole truth. Cap, and you, Hans, old fellow, Phil and I were not taken together, because Phil was never taken at all. It was I alone who sat still, shut my eyes, and closed my ears while I let three of the ugliest Comanche warriors that were ever born walk up, lay violent hands on me, harness me up in all sorts of thongs and withes, and carry me off to their village, where they would have had some red sport with me if Phil hadn't come, when they were all mad with a great dance, and taken me away." Then he told the story in detail, and Phil, shy and blushing, was compelled to receive their compliments, which were many and sincere. But he insisted that he merely succeeded through good luck, which Bill Breakstone warmly denied. "Well, between the two of you, you have certainly got out of it well," said Middleton, "and, as we are reunited, we must plan for the next step. We can easily overtake the train by to-morrow, but I'm of the opinion that we'll have to be very careful, and that we must do some scouting, also. Arenberg and I have discovered that the Comanche warriors are on the move again. Their whole force of warriors seemed to be getting ready to leave the village, and they may be planning, after all, a second attack upon the train, a night
  • 63. surprise, or something of that kind. We, too, will have to be careful lest we run into them." "Then it maybe for the good of the train that we were left back here," said Phil, "because we will return with a warning." "It may be the hand of Providence," said Arenberg, "since the Comanches did no harm where much was intended." As both Middleton and Arenberg were firmly convinced that the plain would be thick with Comanche scouts, making their passage by daylight impossible, or at least extremely hazardous, they decided to remain in the woods until nightfall. They rode a couple of miles from the camp, tethered their horses in thick bushes, and, sitting near them, waited placidly. Phil Breakstone, and Arenberg talked in low tones, but Middleton sat silent. Phil noticed presently that "The Cap" was preoccupied. Little lines of thought ran down from his eyes to the corners of his nose. Phil began to wonder again about the nature of Middleton's mission. Every one of the four was engaged upon some great quest, and none of them knew the secret of any of the others. Nor, in the rush of events, had they been left much time to think about such matters. Now Phil again studied Middleton more closely. There was something in the unaccustomed lines of his face and his thoughtful eye indicating a belief that for him, at least, the object of the quest might be drawing nigh. At least, it seemed so to the boy. He studied, too, Middleton's clean cut face, and the sharp line of his strong chin. Phil had noticed before that this man was uncommonly neat in his personal appearance. It was a neatness altogether beyond what one usually saw on the plains. His clothing was always clean and in
  • 64. order, he carried a razor, and he shaved every day. Nor did he ever walk with a slovenly, lounging gait. Phil decided that something very uncommon must have sent him with the Santa Fé train, but he would not ask; he had far too much delicacy to pry into the secret of another, who did not pry into his own. Middleton and Arenberg had ample food in their saddlebags and Phil and Breakstone combined with it their stock of deer meat. Nothing disturbed them in the thicket, and at nightfall they mounted and rode out into the plain. "I know something about this country before us," said Breakstone. "It runs on in rolling swells for a march of many days, without any streams except shallow creeks, and without any timber except the fringes of cottonwoods along these creeks." "And I know which way to go in order to overtake the train," said Middleton. "Woodfall said that they would head straight west, and we are certainly good enough plainsmen to keep our noses pointed that way." "We are, we surely are," said Bill Breakstone, "but we must keep a good watch for those Comanche scouts. They hide behind the swells on their ponies, and they blend so well with the dusky earth that you'd never notice 'em until they had passed the signal on to others that you were coming and that it was a good time to form an ambush." There was a fair sky, with a moon and some clear stars, and they could see several hundred yards, but beyond that the whole horizon fused into a dusky wall. They rode at a long, swinging pace, and the hoofs of their horses made little noise on the new spring
  • 65. turf. The wind of the plains, which seldom ceases, blew gently in their faces and brought with it a soft crooning sound. Its note was very pleasant in the ears of Philip Bedford. In the saddle and with his best friends again, he felt that he could defy anything. He felt, too, and perhaps the feeling was due to his physical well-being and recovered safety, that he, also, was coming nearer to the object of his quest. Involuntarily he put his left hand on his coat, where the paper which he had read so often lay securely in a little inside pocket. He knew every word of it by heart, but when the time came, and he was alone, he would take it out and read it again. It was this paper that was always calling to him. They rode on, crossing swell after swell, and, after the first hour, the four did not talk. It was likely that every one was thinking of his own secret. They came about midnight to a prairie creek, a stream of water two or three yards wide and a few inches deep, flowing in a bed of sand perhaps fifteen yards across. A thin fringe of low cottonwoods and some willows grew on either shore. They approached warily, knowing that such a place offered a good ambush, and realizing that four would not have much chance against a large Comanche war band. "But I don't think there is much danger," said Bill Breakstone. "If the Comanches are up to mischief again, they're not looking for stray parties; their mind is on the train, and, by the way, the train has passed along here. Look down, and in this moonlight you can see plainly enough the tracks of a hundred wheels." "The horses are confident," said Middleton, "and I think we can be so, too."
  • 66. The horses were advancing without hesitation, and it soon became evident that nothing was concealed among the scanty lines of trees and bushes. "Look out for quicksands," said Arenberg. "It iss not pleasant to be swallowed up in one of them and feel that you have died such a useless death." "There is no danger," said Phil, whose quick eye was following the trail of the wagons. "Here is where the train crossed, and if the wagons didn't sink we won't." The water being cold and entirely free from alkali, the horses drank eagerly, and their riders, also, took the chance to refill their canteens, which they always carried strapped to their saddle bows. They also rested awhile, but, when they remounted and rode on, Middleton noticed a light to the northward. On the plains then, no man would pass a light without giving it particular attention, and the four sat on their horses for some minutes studying it closely. They thought at first that it might be a signal light of the Comanches, but, as it did not waver, they concluded that it must be a camp fire. "Now I'm thinking," said Bill Breakstone, "that we oughtn't to leave a camp fire burning away here on the plains, and we not knowing anything about it. It won't take us long to ride up and inspect it." "That is a truth," said Middleton. "It is not a difficult matter for four horsemen to overtake a wagon train, but we'll first see what that fire means." "It iss our duty to do so," said the phlegmatic German. They rode straight toward the light, and their belief that it was a camp fire was soon confirmed. They saw the red blaze rising and
  • 67. quivering, and then dusky figures passing and repassing before it. "We're yet too far away to tell exactly what those figures are," said Bill Breakstone, "but I don't see any sign of long hair or war bonnets, and so I take it that they are not Comanches, nor any other kind of Indians, for that matter. No warriors would build so careless a fire or wander so carelessly about it. "They are white men," said Middleton with conviction, as he increased his horse's pace. "Ah, I see now! Mexicans! Look at the shadows of their great conical hats as they pass before the fire." "Now I wonder what they're doing here on Texas soil," said Bill Breakstone. Middleton did not answer, but Phil noticed that the look in his eyes was singularly tense and eager. As they drew near the fire, which was a large one, and the hoof-beats of their horses were heard, two men in Mexican. dress, tall conical broad-brimmed hats, embroidered coats and trousers and riding boots, bearing great spurs, came forward to meet them. Phil saw another figure, which had been lying on a blanket by the fire, rise and stand at attention. He instantly perceived, even then, something familiar in the figure. The four rode boldly forward, and Middleton called out: "We are friends!" The two Mexicans who were in advance, rifle in hand, stood irresolutely, and glanced at the man behind them, who had just risen from his blanket. "You are welcome," said this man in good English but with a strong Mexican accent. "We are glad for anybody to share with us our camp fire in this wilderness. Dismount, Señores."
  • 68. Then Phil knew him well. It was Pedro de Armijo, the young Mexican whom he had seen with the Mexican envoy, Zucorra, in New Orleans, one whom he had instinctively disliked, one whom he was exceedingly astonished to see at such a time and place. Middleton also recognized him, because he raised his cap and said politely: "This is a pleasant meeting. You are Captain Pedro de Armijo, who came to our capital with His Excellency Don Augustin Xavier Hernando Zucorra on a mission, intended to be of benefit to both our countries. My name is Middleton, George Middleton, and these are my friends, Mr. Breakstone, Mr. Arenberg, and Mr. Bedford." De Armijo gave every one in turn a quick scrutinizing look, and, with flowing compliment, bade them welcome to his fireside. It seemed that he did not remember Middleton, but that he took for granted their former meeting in Washington. Phil liked him none the more because of the polite words he used. He was not one to hold prejudice because of race, but this Mexican had a manner supercilious and conceited that inspired resentment. "It seems strange, Señor Middleton," said de Armijo, "that we should meet again in such a place on these vast plains, so far from a house or any other human beings, plains that were once Mexican, but which you now call yours." De Armijo glided over the last words smoothly, but the blood leaped in Phil's temples. Middleton apparently took no notice, but said that he and his comrades were riding across the plains mainly on an exploring expedition. As there was some danger from Comanches, they were traveling partly by night, and, having seen the camp fire, they had come to investigate it, after the custom of the wilderness.
  • 69. "And, now that you have found us," said de Armijo with elaborate courtesy, "I have reason to believe that you would run into Comanche horsemen a little farther on. They would not harm us Mexicans, with whom they are at peace, but for you Americans they would have little mercy. Stay with us for the remainder of the night." He smiled, showing his white teeth, and Middleton smiled back as he replied: "Your courtesy is appreciated, Captain de Armijo. We shall stay. It is pleasant, too, to welcome a gallant Mexican officer like yourself to American soil." The eyes of de Armijo snapped in the firelight, and the white teeth were bared again. Phil knew that he resented the expression "American soil." Mexico still maintained a claim to Texas--which it could not make good--and he felt equally confident that Middleton had used it purposely. It seemed to him that some sort of duel was in progress between the two, and he watched it with overwhelming curiosity. But de Armijo quickly returned to his polite manner. "You speak the truth," he said. "It is I who am your guest, not you who are mine. It was Mexican soil once, and before that Spanish--three centuries under our race--but now gone, I suppose, forever." Middleton did not reply, but approached the fire and warmed his hands over the blaze. The night was cold and the flames looked cheerful. The others tethered their horses, and all except the two who had met the Americans took their places by the fire. The Mexicans were six in number. Only de Armijo seemed to be a man of any distinction. The others, although stalwart and well armed, were evidently of the peon class. Phil wondered what this little party was
  • 70. doing here, and the conviction grew upon him that the meeting had something to do with Middleton's mission. "I am sorry," said de Armijo, "that we do not even have a tent to offer you, but doubtless you are accustomed to sleeping under the open sky, and the air of these plains is dry and healthy." "A blanket and a few coals to warm one's feet are sufficient," said Middleton. "We will avail ourselves of your courtesy and not keep you awake any longer." Both Breakstone and Arenberg glanced at Middleton, but they said nothing, wrapping themselves in their blankets, and lying down, with their feet to the fire. Phil did the same, but he thought it a strange proceeding, this apparently unguarded camping with Mexicans, who at the best were not friends, with the possibility of Comanches who were, at all times, the bitterest and most dangerous of enemies. Yet Middleton must have some good reason, he was not a man to do anything rash or foolish, and Phil awaited the issue with confidence. Phil could not sleep. The meeting had stirred him too much, and his nerves would not relax. He lay before the fire, his feet within a yard of the coals, and his head in the crook of his arm. Now and then he heard a horse move or stamp his hoofs, but all the men were silent. De Armijo, lying on a blanket and with a fine blue cavalry cloak spread over him, seemed to be asleep, but as he was on the other side of the fire Phil could not see his eyes. Middleton was nearer, and he saw his chest rising and falling with the regularity of one who sleeps. It all seemed very peaceful, very restful. Perhaps de Armijo's hospitality was real, and he had wronged him with his suspicions.
  • 71. But reason with himself as he would, Phil could not overcome his dislike and distrust. Something was wrong, and something was going to happen, yet much time passed and nothing happened. De Armijo's eyes were still shaded by his cloak, but his long figure lay motionless. Only a few live coals remained from the fire, and beyond a radius of twenty feet lay the encircling rim of the darkness. At the line where light and dark met, crouched the two peons with their rifles across their knees. It was Phil's opinion that they, too, slept in this sitting posture. Surely de Armijo and his men had great confidence in their security, and must be on the best of terms with the Comanches! If so, it might increase the safety of the little American party, also, but the boy yet wondered why Middleton had stopped when they were all so eager to reach the wagon train and warn it of the new danger. Phil stirred once or twice, but only to ease his position, and he did it without noise. His eyes were shaded by the brim of his soft hat, but he watched the circle about the fire, and most of all he watched de Armijo. An interminable period of time passed, every second growing to ten times its proper length. Phil was as wakeful as ever, but so much watching made the figures about the fire dim and uncertain. They seemed to shift their places, but the boy was still resolved to keep awake, although everybody else slept through the night. His premonition was yet with him, his heart expanded, and his pulse beat faster. The remaining coals died one by one. The circle of light, already small, contracted still more, became a point, and then vanished. Everything now lay in the dark, and the figures were merely blacker shapes against the blackness. Then, after that long waiting, with
  • 72. every second and minute drawn out tenfold, Phil's premonition came true. Something happened. De Armijo moved. He moved ever so slightly, but Phil saw him, and, lying perfectly still himself, he watched him with an absorbed attention, and a heart that had increased its beating still further. De Armijo's body itself had not moved, it was merely one hand that had come slowly from under the covering of the cloak, and that now lay white against the blue cloth. A man might move his hand thus in sleep, but it seemed to Phil that the action was guided by a conscious mind. Intent, he watched, and presently his reward came. The other hand also slid from beneath the cloak, and, like its fellow, lay white against the blue cloth. Now both hands were still, but Phil yet waited, confident that more would come. It was all very quiet and slow, like the craft and cunning of the Indian, but Phil was willing to match it with a patience and craft of his own. At last the whole figure of de Armijo stirred. Phil saw the blue cloak tremble slightly. Then the man raised his head ever so little and looked about the dark circle. Slowly he let the head fall back, and the figure became still again. But the boy was not deceived. Already every suspicion had been verified in his mind, and his premonition was proved absolutely true. Pedro de Armijo raised himself again, but a little higher this time, and he did not let his head and body drop back. He looked about the circle with a gaze that Phil knew must be sharp and scrutinizing, although it was too dark for him to see the expression of his eyes. The Mexican seemed satisfied with his second examination, and then, dropping softly on his hands and knees, he crept toward Middleton. It occurred to Phil afterward that this
  • 73. approach toward Middleton did not surprise him. In reality, it was just what he had expected de Armijo to do. The boy was uncertain about his own course, and, like one under a spell, he waited. The dusky figure of de Armijo creeping toward Middleton had a sinuous motion like that of a great snake, and Phil's hand slipped down to the hammer of his rifle, but he would not fire. He noticed that de Armijo had drawn no weapon, and he did not believe that murder was his intention. Middleton did not move. He lay easily upon his right side, and Phil judged that he was in a sound sleep. De Armijo, absorbed in his task, did not look back. Hence he did not see the boy who rose slowly to a sitting posture, a ready rifle in his hands. Phil saw de Armijo reach Middleton's side and pause there a moment or two. He still drew no weapon, and this was further proof that murder was not in the Mexican's mind, but Phil believed that whatever lay between these two was now at the edge of the crisis. He saw de Armijo raise his hand and put it to Middleton's breast with the evident intention of opening his coat. So he was a thief! But the fingers stopped there as Phil leveled his rifle and called sharply: "Hands up, de Armijo, or I shoot!" The startled Mexican would have thrown up his hands, but he did not have time. They were seized in the powerful grasp of Middleton, and he was pulled downward upon his face. "Ah, would you, de Armijo!" cried Middleton in exultant tones. "We have caught you! Good boy, Phil, you were watching, too!" "All the others were up in an instant, but Breakstone and Arenberg were too quick for the Mexicans. They covered them with their rifle muzzles before their antagonists could raise their weapons.
  • 74. "Throw down every gun and pistol!" said Breakstone sternly. "There, by the log, and we'll see what's going forward!" Sullenly the Mexicans complied, and then stood in a little huddled group, looking at their fallen leader, whom Middleton still held upon the ground, but who was pouring out muffled oaths from a face that was in the dirt. "Take his pistols, Phil," said Middleton, and the boy promptly removed them. Then Middleton released him, and de Armijo sat up, his face black as night, his heart raging with anger, hate, and humiliation. "How dare you attack me in my own camp! You whom we received as guests!" he cried. "We did not attack you," replied Middleton calmly. He had risen to his feet, and he towered over the Mexican like an accusing judge. "It is you who attacked us, or me, rather, and you intended, if you did not get what you wanted with smooth fingers, to use violence. You cannot deny that, Captain Pedro de Armijo of the Mexican army; there were at least two witnesses of your act, Philip Bedford and myself." De Armijo looked down at the ground, and seemed to commune with himself for a few moments. Then he stood at his full height, brushed the traces of dirt from his clothes, and gave Middleton a look of uncompromising defiance and hostility. All at once it struck Phil that this was a man of ability and energy, one who could be a bitter and dangerous enemy. "You are right in part, Captain Middleton," said de Armijo slowly. "I was seeking to take the maps, letters, and instructions that you carry inside your tunic, next, perhaps, to your very flesh. They would
  • 75. be valuable possessions to us, and it was my duty, as a captain in the Mexican army, to take them if I could, from you, a captain in the American army." Phil started and looked anew at Middleton. A captain in the American army! This was why he had walked with that upright carriage! This was why he had been so particular about his personal appearance! He began to see a little way. "We, too, have our channels of information," said de Armijo, "and I knew that you had embarked upon a mission in the West to learn our movements and forces upon the border, and our temper and disposition with regard to great matters that are agitating both Mexico and America." "It is true, all that you say," replied Middleton tranquilly. "I am Captain George Middleton of the American regular troops, and, at the request of our War Department, I undertook the hazardous mission of which you speak." "You will go no farther with it," said de Armijo. "How can you keep me from it?" "I cannot--perhaps, but events can--events have. You do not know, but I do, Captain Middleton, that there is war between your country and mine." "Ah!" exclaimed Middleton, and, despite the darkness, Phil saw a sudden flush spring into his face. "It is not only war," continued de Armijo, "but there has been a heavy battle, two of them, in fact. Your troops met ours at Palo Alto on May eighth, and again on the following day at Resaca de la Palma."
  • 76. "Ah!" exclaimed Middleton again, the exclamation being drawn up from the very depths of his being, while the flush on his face deepened. "And you know, I suppose, which won?" It was a peculiar coincidence that the moon's rays made their way at that moment through clouds, and a bright beam fell on the face of Pedro de Armijo. Phil saw the Mexican's face fall a little, despite all his efforts at self-control. De Armijo himself felt this change in his countenance, and, knowing what it indicated to the man who asked the question, he replied without evasion: "I regret to say that the fortunes of war were against the deserving. Our brave general, Ampudia, and our gallant troops were compelled to retire before your general, Taylor. At least, so say my hasty advices; perhaps they are wrong." But Phil could see that de Armijo had no such hope. The news was correct, and the boy's heart thrilled with joy because the first victories had fallen to his own people. "I would not have told you this," continued de Armijo, "had you not caught me in an attempt to take your papers. Had it been peace, 'steal' would have been the word, but since it is war 'steal' turns to enterprise and zeal. Had I not believed you ignorant that the war has begun, and that I might make more profit out of you in our hands than as a fugitive, or at least as one who might have escaped, I should have opened fire upon you as you approached. Perhaps I made a mistake." "All of us do at times," said Middleton thoughtfully. "Well spoken," said de Armijo. He lighted a cigarette and took a few easy puffs.
  • 77. "Well, Captain Middleton," he said at length, "the problem is now yours, not ours. You have taken it out of our hands. What are you going to do with us?" "It seems to me," said Captain Middleton, "that this problem, like most others, admits of only one solution. You are our prisoners, but we cannot hold you. Our own situation prevents it. We could kill you, but God forbid a single thought of such a crime. We will take your arms and let you go. You will not suffer without your arms, as your Comanche friends are near, a fact which you know very well." "We accept your terms," said de Armijo, "since we must, and with your permission we will mount our horses and ride away. But it is to be understood, Captain Middleton, and you, young Mr. Bedford, and the rest of you, that we part as enemies and not as friends." "As you will," said Middleton. "I recognize the fact that you have no cause to love us, and perhaps the sooner we both depart from this spot the better it will be for all." "But we may meet again on the battlefield; is it not so?" said de Armijo. "That, I cannot tell," replied Middleton, "but it is not unlikely." Breakstone and Arenberg still stood by the captured arms, but, without casting a glance at either the arms or their guardians, de Armijo signaled to his men, and they mounted and rode away. "Adios!" he called back in Spanish, although he did not turn his face. "Adios!" said Middleton in the same tone. They did not move or speak until they heard the hoof-beats die away, and then it was Bill Breakstone who first broke the silence.
  • 78. "That certainly came out well," he said. "The curtain came down on a finer finish than the first act indicated. I confess that I didn't know your plan, Captain--I don't call you Cap any more--but I trusted you, and I confess, also, that I fell asleep. It was you and Sir Philip of the Active Mind and the Watchful Eye who did most of the work. "It was in Tex. We met the Mex. They spoke so high, But now they cry. Or, at least, they ought to cry when they think how we turned the tables on them. Now, Captain, I suppose we must be up and doing, for those fellows, as you said, will go straight to the Comanches, and if we linger here our scalps will be of less value to ourselves than to anybody else." "It is quite true," said Captain Middleton. "We must reach the train as soon as possible, because the danger to it has increased with our own. But even more important than that is the great change that must be made. Woodfall cannot go on now, since the whole Southwest will be swept by bands of Mexican and Indian horsemen." "What must the train do?" asked Phil in anxiety, because this concerned him very nearly. "It must turn south and join the American army on the Rio Grande. Most of the things that it carries will be of value to our troops, and Woodfall will clear as much profit there as at Santa Fé,
  • 79. which is now a city in arms against us. In this case the path of comparative safety and honor is also the path of profit. What more could Woodfall ask?" "He's a brave man, and brave men are with him," said Bill Breakstone. "You won't have to ask him twice." Phil's heart had throbbed with joy at Middleton's answer. His quest was always in his mind. He had feared that they might turn back, but now it suited him as well to join the American army as to go on toward Santa Fé. The quest was a wide one. But Arenberg suppressed a sigh. "Let's be starting," said Middleton. "We'll take their arms with us. They're of value, and Bill, moreover, is without a rifle or musket." Breakstone, who had been examining the weapons, uttered a cry of joy. "Here is a fine rifle," he said, "one of the best American make. I wonder how that Mexican got it! The rest are not so good." "Take the fine one, Bill," said Middleton, "and we will pack up the rest and ride." They were out of the woods in a few minutes, and again rode rapidly toward the west. It was an easy task to pick up the great wagon trail again, even in the dark of the night, as the grass and soil were trodden or pressed down over a width of fully two hundred yards. The country rolled lightly. Bill Breakstone thought that a range of hills lay toward the north, but in the night they could not see. "I hope that we'll overtake Woodfall before day," said Middleton, "because I've an idea that de Armijo and the little band with him are not the only Mexicans hereabouts. He would not come so far North
  • 80. without a considerable force, and I suspect that it is his intention to capture our train, with the aid of the Comanches." "We can beat them off," said Breakstone confidently. "If our people are warned in time," said Middleton. "Much harm iss meant," said Arenberg, speaking for the first time, "but we may keep much from being done. Our most dangerous enemies before the daylight comes are the Comanches. They have already learned from de Armijo that we are here, and it iss like as not that they are now between us and the train." Middleton looked at his watch, holding it in the moon's rays. "It is two hours until day," he said, "and the trail is rapidly growing fresher. We may yet get through before the ring closes. Ah, there they are now!" A hand's breadth of fire suddenly leaped up in the north, and burned there like a steady torch. Far in the east, another but fainter appeared and burned, and a third leaped up in the south. But when they looked back in the west they saw none. "Fortune rides on our cruppers so far," said Middleton. "We are on the side of the circle which yet has the open segment. Push on, my boys!" Phil's knees involuntarily pressed against the side of his horse, and that strange sensation, like icy water running down the spine, came again. Those three lights speaking to one another in the darkness and across great distances were full of mystery and awe. But he rode without speech, and he looked most of the time at the lights, which remained fixed, as if what they said could not be changed.
  • 81. Middleton, who was in advance, suddenly reined in his horse, and the others, stopping, also, noticed that just in front of them a depression ran across the plain. "It's an arroyo or something like it," said Bill Breakstone, "but the wagons have crossed it anyhow." They followed the trail to the other side and then saw that it continued almost parallel with the broad gully. "Why shouldn't we take to the gully?" said Phil. "It has a smooth bottom, it is wide enough for us, riding two abreast, and it will give us shelter." "A good idea," said Middleton. They turned back into the arroyo, and found an easy road there. The banks were several feet high, and, as the dusk still hung on the plain, they increased their speed, counting each moment worth one man's life. They came soon to a place where the gully was shallower than usual, and then they saw two or three faint lights in the plain before them, apparently about a half mile away. Middleton raised a warning hand, and they stopped. "Those are the lights of the train," he said. "They undoubtedly have scouts out, and of course they have seen the signals of the Comanches and the Mexicans, just as we have, but they do not know as much as we do. I think we had better go down the arroyo as far as we can, and then, if the alarm is sounded by our enemies, gallop for it." "It iss our choice because there iss none other," said Arenberg. They continued, but more slowly, in order to make as little noise as possible. They had covered more than half the distance when Phil saw a faint line of gray on the horizon line in the east. The next
  • 82. moment against the background of gray appeared a horseman, a man of olive skin, clad in sombrero, bright jacket, embroidered trousers, and boots with great spurs. He carried a weapon like a spear, and Phil knew at once that he was a Mexican lancer, no doubt a sentinel. The man saw them, and, instead of attempting to use his lance, snatched a pistol from his belt and fired point blank. The bullet passed by Middleton's face, and, like a flash, Bill Breakstone replied with a bullet from his rifle. The Mexican went down, but from three points of the compass came cries, the shouts of the Mexicans and the long war whoop of the Comanches. "Forward for your lives!" cried Middleton, and, dashing out of the arroyo, they galloped at full speed toward the wagon train.
  • 83. CHAPTER IX THE FIERY CIRCLE The thin gray light in the east broadened into a bar as the hoofbeats of the four thundered over the plain. From left to right came shouts, the yells of the Indians and the fierce cries of the Mexicans. "Bend low," cried Middleton, "and we may escape their bullets!" Phil lay almost upon his horse's neck, but it was an unconscious act. He was thrilling with excitement, as the four horsemen almost clove the morning mist, and rode on swift hoofs straight toward the wagon train. Then came the rattling of rifles and whistling of arrows from either side. "Ping!" the bullets sang in his ear and "Ping!" the arrows sang, also. He remembered afterward that he wished, if he were hit at all, to be hit by a bullet instead of an arrow; an arrow sticking in one's flesh would be very cumbersome and painful. But neither arrow nor bullet struck true. Their ride was too sudden and swift, and the light too faint to permit good aim to the Mexicans and Comanches. Yet Phil heard confused sounds, shouted commands, and the noise of hurrying feet. He saw dark faces appearing in the mist on either side, and he also saw the outlines of wagons through the same mist in front. Then he saw men, rifle in hand, who seemed to rise out of the plain in front of the wagons. Two of the men raised their rifles and took aim at the galloping horsemen. "We are friends, and we bring you warning!" shouted Middleton in a tremendous voice. "Don't fire upon us!"
  • 84. But the men and three others who appeared near them pulled the trigger. Phil did not hear the ping of the bullets, and now he realized that they fired not at his comrades and himself but at those who pursued. A death-cry and yells of rage came from behind them, but in another minute they were within the line of sentinels and were springing from their horses, ready to take their part in the combat that they expected. All the morning mists were driven away at that moment by the sun, as if a veil had been lifted, and the whole plain stood out clear and distinct under a brilliant sky. Before them were the wagons, drawn up in a circle in the customary fashion of a camp, the horses and mules in the center, and the men, arms in hand, forming an outer ring for the wagons. But from the northeast and the southeast two lines were converging upon them, and Phil's heart kindled at the sight. The line in the northeast was made up of red horsemen, four hundred Comanches, naked to the waist, horribly painted, and riding knee to knee, the redoubtable chiefs, Santana and Black Panther, at their head. The line in the southeast was composed of Mexican cavalry, lancers splendidly mounted, the blades of their lances and their embroidered jackets glittering in the sun. They made their horses prance and cavort, and many in the first rank whirled lariats in derision. A tall figure strolled forward and welcomed Middleton and his comrades. It was Woodfall, his face flushed somewhat, but his manner undaunted. "I'm glad to welcome you back, Mr. Middleton," he said, "and with your comrades, all of them alive and well. But what does this
  • 85. mean? Why do those men ride to attack, when this is the soil of Texas?" He waved his hand toward the advancing Mexican column. "They advance against us," replied Middleton, "because this is war, war between the United States and Mexico--we learned that last night from one of their own officers--and there have been two heavy battles on the Rio Grande, both victorious for us." It was not strange that a sudden cheer burst from the men who heard these words. Woodfall listened to it grimly, and, when it died, he said: "Then if these Mexicans attack, we'll soon have a third victory to our credit. The Indian bow and the Mexican lance can't break through a circle of riflemen, entrenched behind wagons--riflemen who know how to shoot." Again that defiant, even exultant cheer rose from the men who heard, and, passing on like a fire in dry grass, it rolled all around the circle of wagons. The Mexicans heard it. They detected the defiant note in it, and, wisely, they checked their speed. The column of Indian warriors also came more slowly. Philip Bedford, hardened in so brief a space to danger and war, did not feel any great fear, but the scene thrilled him like a great picture painted in living types and colors against the background of the earth. There were the red horsemen, the sun deepening the tints of their coppery faces and bringing out the glowing colors of their war bonnets. To the southeast the Mexican column, also, was a great ribbon of light lying across the plain, the broad blades of the lances catching the sun's rays and throwing them back in golden beams.
  • 86. "A fine show," said Woodfall, "and if those Mexicans had two or three cannon they might wipe us out, but they haven't, and so we're lucky." "I think I ought to tell you, Mr. Woodfall," said Middleton, "that I'm a captain in the regular army, Captain Middleton, and that I've been making use of your hospitality to find what forces the enemy had in these parts, and what movements he was making. I was sent by our government, and, as you see, I'm finding what I was sent to find." "I thought there was something military about your cut, Captain," said Woodfall, "and it seems to me to be a good thing that you are with us. If we've helped you without knowing, then you, knowing it, can help us now." The hands of the two men met in the strong clasp of friendship and trust. "They're about to move," said Middleton, who practically took command. "I suggest that we go inside the circle of wagons now, and that at least two-thirds of our men devote their attention to the lancers. The Mexicans are brave; we must not forget that." They went inside at once, where a few men were detailed to see that the horses and mules did not make too great a turmoil, while the rest posted themselves for defense. The wagons were in reality a formidable barrier for an attacking force that did not have artillery. The majority of the Americans lay down under the wagons between the wheels. Phil was under one of them with Bill Breakstone on one side of him and Arenberg on the other. Middleton was elsewhere with Woodfall.
  • 87. "Much harm iss meant," said Arenberg, "and I would say to you, Philip, although little advice iss needed by you now, not to fire too soon, and to remember, when you take aim, to allow for the fact that they are coming toward us at a gallop." "That's right," said Bill Breakstone. "Old Hans, here, knows." "Ach," said Arenberg, uttering a sigh, "I love peace, and I never thought to have a part in cruel Indian and Mexican battles." It occurred to Phil that the sigh had no reference to the coming combat. The German's face showed sadness, but not a trace of fear. He turned his gaze from Arenberg and fixed it upon the Mexican column which they were facing. He thought that he saw de Armijo in the front rank among the officers in brilliant dress, but he was not sure. The distance was too great. He wondered whether he would shoot at him, if he saw him later in the charge. The sunlight was intensely bright, such as one sees only on great upland plains, and the Mexican lancers with their horses stood out, like carving, against the background of gold and blue. Phil saw the column suddenly quiver, as if a single movement ran through all. The lances were lifted a little higher, and their blades cast broader beams. A flag fluttered in the front rank and unfolded in the slight wind. The notes of a trumpet sounded high and clear, the Mexicans uttered a long, fierce shout, the colors shifted and changed, like water flowing swiftly, as the column broke into a gallop and came straight toward the wagons, the plain thundering with the beat of their hoofs. From another part of the compass came a second cry, higher pitched, longer drawn, and with more of the whine of the wolf in it. Phil knew that it came from the Comanches, who were
  • 88. also charging, led by Black Panther and Santana, but he did not take his eyes from the Mexicans. The two attacking columns began to fire scattering shots, but the defenders of the wagons had not yet pulled a trigger, although many a forefinger was trembling with eagerness. "It's pretty, but it's a waste, a dead waste," said Bill Breakstone. "I hate to shoot at them, because I've no doubt many a brave young fellow is out there, but we've got to let them have it. Steady, Phil, steady! They're coming close now." Suddenly they heard the loud shout, "Fire!" It was Middleton who uttered it, and everybody obeyed. A sheet of flame seemed to spurt from the wagons, and the air was filled with singing lead. The entire head of the Mexican column was burnt away. The ground was strewn with the fallen. Riderless horses, some wounded and screaming with pain, galloped here and there. The column stopped and seemed to be wavering. Several officers, sword in hand--and now Phil was sure that he saw de Armijo among them--were trying to urge the lancers on. All the Americans were reloading as fast as they could, and while the Mexicans yet wavered, they poured in a second volley. Unable to withstand it, the lancers broke and fled, bearing the officers away with them in their panic. Phil, Bill Breakstone, and Arenberg crawled from under the wagon and stood on the outside, erect again. There they contemplated for a few moments the wreck that they and their comrades had made. From the Indian point of attack came the sound of retiring shots, and they knew that the Comanches had been quickly repulsed, also.
  • 89. "It was one of the most foolish things I ever saw," said Bill Breakstone, "to ride right into the mouths of long-barreled, well- aimed rifles like ours. Their numbers didn't help them. What say you, Sir Philip of the Rifle and the Wagon?" "It seems to me that you're right," replied the boy. "I don't think they'll charge again, nor will the Comanches." "You're right, too; they've had enough." The Mexicans and Comanches, having gathered up their wounded, united and remained in a dark cloud beyond rifle shot, apparently intending neither to charge again nor to go away. But the defenders of the train were cheerful. They had suffered no loss, being protected so well, and they were willing enough to meet a second attack delivered in the same fashion. But Middleton and Woodfall had hot coffee and tea served, and then with strong field glasses they observed the enemy. "I believe they are in great doubt," said Middleton. "They may think they can starve us out, but the Mexicans will not want to wait for so long a process; it is likely that they will prefer going southward to join their main army." He said these words aloud, where many could hear, but a little while afterward he and Woodfall drew to one side and talked a long time in low tones. Phil could tell by their faces that they were very earnest, and he felt sure that a proposition would be made before long. He called Breakstone's attention to them. "You're right," said Bill, "they'll have something to say soon, and it will concern all of us. Ah, there comes the Cap--I mean the Captain--now, and he's going to make a speech."
  • 90. Welcome to our website – the perfect destination for book lovers and knowledge seekers. We believe that every book holds a new world, offering opportunities for learning, discovery, and personal growth. That’s why we are dedicated to bringing you a diverse collection of books, ranging from classic literature and specialized publications to self-development guides and children's books. More than just a book-buying platform, we strive to be a bridge connecting you with timeless cultural and intellectual values. With an elegant, user-friendly interface and a smart search system, you can quickly find the books that best suit your interests. Additionally, our special promotions and home delivery services help you save time and fully enjoy the joy of reading. Join us on a journey of knowledge exploration, passion nurturing, and personal growth every day! ebookbell.com