@@ -14,49 +14,50 @@ ms.assetid: 883cd93d-50ce-4144-b7c9-2df28d9c11a0
1414
1515# Console Application
1616
17- ## Introduction
1817This tutorial teaches you a number of features in .NET Core and the C# language. You’ll learn:
19- * The basics of the .NET Core Command Line Interface (CLI)
20- * The structure of a C# Console Application
21- * Console I/O
22- * The basics of File I/O APIs in .NET Core
23- * The basics of the Task Asynchronous Programming Model in .NET Core
18+
19+ - The basics of the .NET Core Command Line Interface (CLI)
20+ - The structure of a C# Console Application
21+ - Console I/O
22+ - The basics of File I/O APIs in .NET
23+ - The basics of the Task-based Asynchronous Programming in .NET
2424
2525You’ll build an application that reads a text file, and echoes the
26- contents of that text file to the console. The output to the console will
27- be paced to match reading it aloud. You can speed up or slow down the pace
26+ contents of that text file to the console. The output to the console is paced to match reading it aloud. You can speed up or slow down the pace
2827by pressing the ‘<’ or ‘>’ keys.
2928
30- There are a lot of features in this tutorial. Let’s build them one by one.
29+ There are a lot of features in this tutorial. Let’s build them one by one.
30+
3131## Prerequisites
32- You’ll need to setup your machine to run .NET core. You can find the
32+
33+ You’ll need to setup your machine to run .NET Core. You can find the
3334installation instructions on the [ .NET Core] ( https://www.microsoft.com/net/core )
3435page. You can run this
35- application on Windows, Linux, macOS or in a Docker container.
36- You’ll need to install your favorite code editor.
36+ application on Windows, Linux, macOS or in a Docker container.
37+ You’ll need to install your favorite code editor.
38+
3739## Create the Application
40+
3841The first step is to create a new application. Open a command prompt and
3942create a new directory for your application. Make that the current
4043directory. Type the command ` dotnet new console ` at the command prompt. This
4144creates the starter files for a basic "Hello World" application.
4245
4346Before you start making modifications, let’s go through the steps to run
4447the simple Hello World application. After creating the application, type
45- ` dotnet restore ` ( [ see note ] ( #dotnet-restore-note ) ) at the command prompt. This command runs the NuGet
48+ ` dotnet restore ` at the command prompt. This command runs the NuGet
4649package restore process. NuGet is a .NET package manager. This command
4750downloads any of the missing dependencies for your project. As this is a
4851new project, none of the dependencies are in place, so the first run will
4952download the .NET Core framework. After this initial step, you will only
50- need to run ` dotnet restore ` ([ see note] ( #dotnet-restore-note ) ) when you add new dependent packages, or update
51- the versions of any of your dependencies. This process also creates the
52- project lock file (project.lock.json) in your project directory. This file
53- helps to manage the project dependencies. It contains the local location
54- of all the project dependencies. You do not need to put the file in source
55- control; it will be generated when you run ` dotnet restore ` ([ see note] ( #dotnet-restore-note ) ).
53+ need to run ` dotnet restore ` when you add new dependent packages, or update
54+ the versions of any of your dependencies.
55+
56+ [ !INCLUDE[ DotNet Restore Note] ( ~/includes/dotnet-restore-note.md )]
5657
5758After restoring packages, you run ` dotnet build ` . This executes the build
5859engine and creates your application executable. Finally, you execute ` dotnet run ` to
59- run your application.
60+ run your application.
6061
6162The simple Hello World application code is all in Program.cs. Open that
6263file with your favorite text editor. We’re about to make our first changes.
@@ -68,19 +69,19 @@ using System;
6869
6970This statement tells the compiler that any types from the ` System ` namespace
7071are in scope. Like other Object Oriented languages you may have used, C#
71- uses namespaces to organize types. This hello world program is no
72- different. You can see that the program is enclosed in the
73- ` ConsoleApplication ` namespace. That’s not a very descriptive name, so
74- change it to ` TeleprompterConsole ` :
72+ uses namespaces to organize types. This Hello World program is no
73+ different. You can see that the program is enclosed in the namespace with the name
74+ based on the name of the current directory. For this tutorial, let's change the name of the namespace to ` TeleprompterConsole ` :
7575
7676``` csharp
7777namespace TeleprompterConsole
7878```
7979
8080## Reading and Echoing the File
81+
8182The first feature to add is the ability to read a text file and display all that text to the console . First , let ’s add a text file . Copy the [sampleQuotes .txt ](https :// github.com/dotnet/samples/raw/master/csharp/getting-started/console-teleprompter/sampleQuotes.txt) file from the GitHub repository for this [sample](https://github.com/dotnet/samples/tree/master/csharp/getting-started/console-teleprompter) into your project directory. This will serve as the script for your application. If you would like information on how to download the sample app for this topic, see the instructions in the [Samples and Tutorials](../../samples-and-tutorials/index.md#viewing-and-downloading-samples) topic.
8283
83- Next , add the following method in your Program class (right below the `Main ` method ):
84+ Next , add the following method in your ` Program ` class (right below the `Main ` method ):
8485
8586```csharp
8687static IEnumerable <string > ReadFrom (string file )
@@ -96,61 +97,61 @@ static IEnumerable<string> ReadFrom(string file)
9697}
9798```
9899
99- This method uses types from two new namespaces. For this to compile you’ll
100+ This method uses types from two new namespaces. For this to compile you’ll
100101need to add the following two lines to the top of the file:
101102
102103``` csharp
103104using System .Collections .Generic ;
104105using System .IO ;
105106```
106107
107- The ` IEnumerable<T> ` interface is defined in the
108- ` System.Collections.Generic ` namespace. The < xref:System.IO.File > class is defined in the
109- ` System.IO ` namespace.
108+ The < xref:System.Collections.Generic.IEnumerable%601 > interface is defined in the
109+ < xref:System.Collections.Generic > namespace. The < xref:System.IO.File > class is defined in the < xref:System.IO > namespace.
110110
111- This method is a special type of C# method called an * Enumerator method* .
111+ This method is a special type of C# method called an * Iterator method* .
112112Enumerator methods return sequences that are evaluated lazily. That means
113113each item in the sequence is generated as it is requested by the code
114114consuming the sequence. Enumerator methods are methods that contain one or
115- more ` yield return ` statements. The object returned by the ` ReadFrom `
115+ more [ ` yield return ` ] ( ../language-reference/keywords/yield.md ) statements. The object returned by the ` ReadFrom `
116116method contains the code to generate each item in the sequence. In this
117117example, that involves reading the next line of text from the source file,
118118and returning that string. Each time the calling code requests the next
119119item from the sequence, the code reads the next line of text from the file
120- and returns it. When the file has been completely read, the sequence
120+ and returns it. When the file is completely read, the sequence
121121indicates that there are no more items.
122122
123- There are two other C# syntax elements that may be new to you. The ` using `
123+ There are two other C# syntax elements that may be new to you. The [ ` using ` ] ( ../language-reference/keywords/using-statement.md )
124124statement in this method manages resource cleanup. The variable that is
125125initialized in the ` using ` statement (` reader ` , in this example) must
126- implement the ` IDisposable ` interface. The < xref:System.IDisposable > interface
126+ implement the < xref:System.IDisposable > interface. That interface
127127defines a single method, ` Dispose ` , that should be called when the
128128resource should be released. The compiler generates that call when
129129execution reaches the closing brace of the ` using ` statement. The
130130compiler-generated code ensures that the resource is released even if an
131131exception is thrown from the code in the block defined by the using
132132statement.
133133
134- The ` reader ` variable is defined using the ` var ` keyword. ` var ` defines an
134+ The ` reader ` variable is defined using the ` var ` keyword. [ ` var ` ] ( ../language-reference/keywords/var.md ) defines an
135135* implicitly typed local variable* . That means the type of the variable is
136- determined by the compile time type of the object assigned to the
136+ determined by the compile- time type of the object assigned to the
137137variable. Here, that is the return value from the < xref:System.IO.File.OpenText(System.String) > method, which is
138138a < xref:System.IO.StreamReader > object.
139-
140- Now, let’s fill in the code to read the file in the ` Main ` method:
139+
140+ Now, let’s fill in the code to read the file in the ` Main ` method:
141141
142142``` csharp
143143var lines = ReadFrom (" sampleQuotes.txt" );
144144foreach (var line in lines )
145145{
146- Console .WriteLine (line );
146+ Console .WriteLine (line );
147147}
148148```
149149
150- Run the program (using ` dotnet run ` and you can see every line printed out
151- to the console).
150+ Run the program (using ` dotnet run ` ) and you can see every line printed out
151+ to the console.
152152
153153## Adding Delays and Formatting output
154+
154155What you have is being displayed far too fast to read aloud. Now you need
155156to add the delays in the output. As you start, you’ll be building some of
156157the core code that enables asynchronous processing. However, these first
@@ -188,7 +189,7 @@ if (!string.IsNullOrWhiteSpace(line))
188189}
189190```
190191
191- The ` Task ` class is in the ` System.Threading.Tasks ` namespace, so you need
192+ The < xref:System.Threading.Tasks. Task> class is in the < xref: System.Threading.Tasks> namespace, so you need
192193to add that ` using ` statement at the top of file:
193194
194195``` csharp
@@ -202,12 +203,12 @@ issues because the source text file has several lines that have more than
202203scrolling by. That’s easy to fix. You’ll just keep track of the length of
203204each line, and generate a new line whenever the line length reaches a
204205certain threshold. Declare a local variable after the declaration of
205- ` words ` that holds the line length:
206+ ` words ` in the ` ReadFrom ` method that holds the line length:
206207
207208``` csharp
208209var lineLength = 0 ;
209210```
210-
211+
211212Then, add the following code after the ` yield return word + " "; ` statement
212213(before the closing brace):
213214
@@ -219,11 +220,12 @@ if (lineLength > 70)
219220 lineLength = 0 ;
220221}
221222```
222-
223+
223224Run the sample, and you’ll be able to read aloud at its pre-configured
224225pace.
225226
226227## Async Tasks
228+
227229In this final step, you’ll add the code to write the output asynchronously
228230in one task, while also running another task to read input from the user
229231if they want to speed up or slow down the text display. This has a few
@@ -238,10 +240,10 @@ Add this method to your `Program` class (it’s taken from the body of your
238240private static async Task ShowTeleprompter ()
239241{
240242 var words = ReadFrom (" sampleQuotes.txt" );
241- foreach (var line in words )
243+ foreach (var word in words )
242244 {
243- Console .Write (line );
244- if (! string .IsNullOrWhiteSpace (line ))
245+ Console .Write (word );
246+ if (! string .IsNullOrWhiteSpace (word ))
245247 {
246248 await Task .Delay (200 );
247249 }
@@ -274,6 +276,9 @@ in a console application’s `Main` method, you cannot use the `await`
274276operator. That would result in the application exiting before all tasks
275277have completed.
276278
279+ > [ !NOTE]
280+ > If you use C# 7.1 or later, you can create console applications with [ ` async ` ` Main ` method] ( ../whats-new/csharp-7-1.md#async-main ) .
281+
277282Next, you need to write the second asynchronous method to read from the
278283Console and watch for the ‘<’ and ‘>’ keys. Here’s the method you add for
279284that task:
@@ -309,10 +314,10 @@ To finish this feature, you need to create a new `async Task` returning
309314method that starts both of these tasks (` GetInput ` and
310315` ShowTeleprompter ` ), and also manages the shared data between these two
311316tasks.
312-
317+
313318It’s time to create a class that can handle the shared data between these
314319two tasks. This class contains two public properties: the delay, and a
315- flag to indicate that the file has been completely read:
320+ flag ` Done ` to indicate that the file has been completely read:
316321
317322``` csharp
318323namespace TeleprompterConsole
@@ -331,22 +336,29 @@ namespace TeleprompterConsole
331336 DelayInMilliseconds = newDelay ;
332337 }
333338 }
339+
340+ public bool Done { get ; private set ; }
341+
342+ public void SetDone ()
343+ {
344+ Done = true ;
345+ }
334346 }
335347}
336348```
337349
338350Put that class in a new file, and enclose that class in the
339351` TeleprompterConsole ` namespace as shown above. You’ll also need to add a ` using static `
340- statement so that you can reference the ` Min ` and ` Max ` method without the
341- enclosing class or namespace names. A ` using static ` statement imports the
352+ statement so that you can reference the ` Min ` and ` Max ` methods without the
353+ enclosing class or namespace names. A [ ` using static ` ] ( ../language-reference/keywords/using-static.md ) statement imports the
342354methods from one class. This is in contrast with the ` using ` statements used
343355up to this point that have imported all classes from a namespace.
344356
345357``` csharp
346358using static System .Math ;
347359```
348360
349- The other language feature that’s new is the ` lock ` statement. This
361+ The other language feature that’s new is the [ ` lock ` ] ( ../language-reference/keywords/lock-statement.md ) statement. This
350362statement ensures that only a single thread can be in that code at any
351363given time. If one thread is in the locked section, other threads must
352364wait for the first thread to exit that section. The ` lock ` statement uses an
@@ -391,7 +403,6 @@ private static async Task ShowTeleprompter(TelePrompterConfig config)
391403
392404private static async Task GetInput (TelePrompterConfig config )
393405{
394-
395406 Action work = () =>
396407 {
397408 do {
@@ -414,28 +425,14 @@ This new version of `ShowTeleprompter` calls a new method in the
414425RunTeleprompter ().Wait ();
415426```
416427
417- To finish, you'll need to add the
418- ` SetDone ` method, and the ` Done ` property to the ` TelePrompterConfig ` class:
419-
420- ``` csharp
421- public bool Done => done ;
422-
423- private bool done ;
424-
425- public void SetDone ()
426- {
427- done = true ;
428- }
429- ```
430-
431428## Conclusion
429+
432430This tutorial showed you a number of the features around the C# language
433431and the .NET Core libraries related to working in Console applications.
434432You can build on this knowledge to explore more about the language, and
435433the classes introduced here. You’ve seen the basics of File and Console
436- I/O, blocking and non-blocking use of the Task based Asynchronous
437- programming model , a tour of the C# language and how C# programs are
434+ I/O, blocking and non-blocking use of the Task- based asynchronous
435+ programming, a tour of the C# language and how C# programs are
438436organized and the .NET Core Command Line Interface and tools.
439-
440- <a name =" dotnet-restore-note " ></a >
441- [ !INCLUDE[ DotNet Restore Note] ( ~/includes/dotnet-restore-note.md )]
437+
438+ For more information about File I/O, see the [ File and Stream I/O] ( ../../standard/io/index.md ) topic. For more information about asynchronous programming model used in this tutorial, see the [ Task-based Asynchronous Programming] ( ../..//standard/parallel-programming/task-based-asynchronous-programming.md ) topic and the [ Asynchronous programming] ( ../async.md ) topic.
0 commit comments