Exploring the Top New Features of the CLR

Exclusive offer: get 50% off this eBook here
Microsoft .NET Framework 4.5 Quickstart Cookbook

Microsoft .NET Framework 4.5 Quickstart Cookbook — Save 50%

Get up to date with the exciting new features in .NET 4.5 Framework with these simple but incredibly effective recipes with this book and ebook.

$23.99    $12.00
by Jose Luis Latorre Millas | August 2013 | .NET Enterprise Articles Microsoft

In this article by Jose Luis Latorre Millas, the author of the book Microsoft .NET Framework 4.5 Quickstart Cookbook, we will explore the top new features of the CLR. .NET 4.5 brings many benefits, such as improvements in performance, compatibility, garbage collection, and new features in its structure to provide the overall scenarios it is targeted for, for example, Windows Store apps development.

In this article, we will cover:

  • Creating a portable library
  • Controlling the timeout in regular expressions
  • Defining the culture for an application domain
  • Overriding the default reflection behavior
  • Using the new ZipArchive class
  • Understanding async and await in .NET 4.5
  • Using the new asynchronous file I/O operations

(For more resources related to this topic, see here.)

One of its most important characteristics is that it is an in-place substitution of the .NET 4.0 and only runs on Windows Vista SP2 or later systems.

.NET 4.5 breathes asynchronous features and makes writing async code even easier. It also provides us with the Task Parallel Library (TPL) Dataflow Library to help us create parallel and concurrent applications.

Another very important addition is the portable libraries, which allow us to create managed assemblies that we can refer through different target applications and platforms, such as Windows 8, Windows Phone, Silverlight, and Xbox.

We couldn't avoid mentioning Managed Extensibility Framework (MEF), which now has support for generic types, a convention-based programming model, and multiple scopes.

Of course, this all comes together with a brand-new tooling, Visual Studio 2012, which you can find at http://msdn.microsoft.com/en-us/vstudio. Just be careful if you have projects in .NET 4.0 since it is an in-place install.

For this article I'd like to give a special thanks to Layla Driscoll from the Microsoft .NET team who helped me summarize the topics, focus on what's essential, and showcase it to you, dear reader, in the most efficient way possible. Thanks, Layla.

There are some features that we will not be able to explore through this article as they are just there and are part of the CLR but are worth explaining for better understanding:

  • Support for arrays larger than 2 GB on 64-bit platforms, which can be enabled by an option in the app config file.
  • Improved performance on the server's background garbage collection, which must be enabled in the <gcServer> element in the runtime configuration schema.
  • Multicore JIT: Background JIT (Just In Time) compilation on multicore CPUs to improve app performance. This basically creates profiles and compiles methods that are likely to be executed on a separate thread.
  • Improved performance for retrieving resources.
  • The culture-sensitive string comparison (sorting, casing, normalization, and so on) is delegated to the operating system when running on Windows 8, which implements Unicode 6.0. On other platforms, the .NET framework will behave as in the previous versions, including its own string comparison data implementing Unicode 5.0.

Next we will explore, in practice, some of these features to get a solid grasp on what .NET 4.5 has to offer and, believe me, we will have our hands full!

Creating a portable library

Most of us have often struggled and hacked our code to implement an assembly that we could use in different .NET target platforms. Portable libraries are here to help us to do exactly this.

Now there is an easy way to develop a portable assembly that works without modification in .NET Framework, Windows Store apps style, Silverlight, Windows Phone, and XBOX 360 applications.

The trick is that the Portable Class Library project supports a subset of assemblies from these platforms, providing us a Visual Studio template.

This article will show you how to implement a basic application and help you get familiar with Visual Studio 2012.

Getting ready

In order to use this section you should have Visual Studio 2012 installed. Note that you will need a Visual Studio 2012 SKU higher than Visual Studio Express for it to fully support portable library projects.

How to do it...

Here we will create a portable library and see how it works:

  1. First, open Visual Studio 2012 and create a new project. We will select the Portable Class Library template from the Visual C# category.
  2. Now open the Properties dialog box of our newly created portable application and, in the library we will see a new section named Target frameworks. Note that, for this type of project, the dialog box will open as soon as the project is created, so opening it will only be necessary when modifying it afterwards.

  3. If we click on the Change button, we will see all the multitargeting possibilities for our class.

  4. We will see that we can target different versions of a framework. There is also a link to install additional frameworks. The one that we could install right now is XNA but we will click on Cancel and let the dialog box be as it is.
  5. Next, we will click on the show all files icon at the top of the Solution Explorer window (the icon with two papers and some dots behind them), right-click on the References folder, and click on Add Reference. We will observe on doing so that we are left with a .NET subset of assemblies that are compatible with the chosen target frameworks.

  6. We will add the following lines to test the portable assembly:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace pcl_myFirstPcl
    {
    public static class MyPortableClass
    {
    public static string GetSomething()
    {
    return "I am a portable class library";
    }
    }
    }

  7. Build the project.
  8. Next, to try this portable assembly we could add, for example, a Silverlight project to the solution, together with an ASP.NET Web application project to wrap the Silverlight.
  9. We just need to add a reference to the portable library project and add a button to the MainPage.xaml page that calls the portable library static method we created.
  10. The code behind it should look as follows. Remember to add a using reference to our portable library namespace.

    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using pcl_myFirstPcl;
    namespace SilverlightApplication_testPCL
    {
    public partial class MainPage : UserControl
    {
    public MainPage()
    {
    InitializeComponent();
    }
    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
    String something = MyPortableClass.GetSomething();
    MessageBox.Show("Look! - I got this string from my portable class
    library: " + something);
    }
    }
    }

  11. We can execute the code and check if it works.
  12. In addition, we could add other types of projects, reference the Portable Library Class, and ensure that it works properly.

How it works...

We created a portable library from the Portable Class Library project template and selected the target frameworks.

We saw the references; note that it reinforces the visibility of the assemblies that break the compatibility with the targeted platforms, helping us to avoid mistakes.

Next we added some code, a target reference application that referenced the portable class, and used it.

There's more...

We should be aware that when deploying a .NET app that references a Portable Class Library assembly, we must specify its dependency to the correct version of the .NET Framework, ensuring that the required version is installed.

A very common and interesting usage of the Portable Class Library would be to implement MVVM. For example, we could put the View Model and Model classes inside a portable library and share it with Windows Store apps, Silverlight, and Windows Phone applications. The architecture is described in the following diagram, which has been taken from MSDN (http://msdn.microsoft.com/en-us/library/hh563947%28v=vs.110%29.aspx):

It is really interesting that the list of target frameworks is not limited and we even have a link to install additional frameworks, so I guess that the number of target frameworks will eventually grow.

Controlling the timeout in regular expressions

.NET 4.5 gives us improved control on the resolution of regular expressions so we can react when they don't resolve on time. This is extremely useful if we don't control the regular expressions/patterns, such as the ones provided by the users.

A badly formed pattern can have bad performance due to excessive backtracking and this new feature is really a lifesaver.

How to do it...

Next we are going to control the timeout in the regular expression, where we will react if the operation takes more than 1 millisecond:

  1. Create a new Visual Studio project of type Console Application, named caRegexTimeout.
  2. Open the Program.cs file and add a using clause for using regular expressions:

    Using System.Text.RegularExpressions;

  3. Add the following method and call it from the Main function:

    private static void ExecuteRegexExpression() {
    bool RegExIsMatch = false;
    string testString = "One Tile to rule them all, One Tile to find
    them… ";
    string RegExPattern = @"([a-z ]+)*!";
    TimeSpantsRegexTimeout = TimeSpan.FromMilliseconds(1);
    try
    {
    RegExIsMatch = Regex.IsMatch(testString, RegExPattern,
    RegexOptions.None, tsRegexTimeout);
    }
    catch (RegexMatchTimeoutException ex)
    {
    Console.WriteLine("Timeout!!");
    Console.WriteLine("- Timeout specified: " + ex.MatchTimeout);
    }
    catch (ArgumentOutOfRangeException ex)
    {
    Console.WriteLine("ArgumentOutOfRangeException!!");
    Console.WriteLine(ex.Message);
    }
    Console.WriteLine("Finished succesfully: " + RegExIsMatch.
    ToString());
    Console.ReadLine();
    }

  4. If we execute it, we will see that it doesn't fi nish successfully, showing us some details in the console window.

  5. Next, we will change testString and RegExPattern to:

    String testString = "jose@brainsiders.com";
    String RegExPattern = @"^([\w-\.]+)@([\w-\.]+)\.[a-zA-Z]{2,4}$";

  6. If we run it, we will now see that it runs and fi nishes successfully.

How it works...

The RegEx.IsMatch() method now accepts a parameter, which is matchTimeout of type TimeSpan, indicating the maximum time that we allow for the matching operation. If the execution time exceeds this amount, RegexMatchTimeoutException is launched.

In our code, we have captured it with a try-catch statement to provide a custom message and of course to react upon a badly formed regex pattern taking too much time.

We have tested it with an expression that will take some more time to validate and we got the timeout. When we changed the expression to a good one with a better execution time, the timeout was not reached.

Additionally, we also watched out for the ArgumentOutOfRangeException, which is thrown when TimeSpan is zero, or negative, or greater than 24 days.

There'smore...

We could also set a global matchTimeout for the application through the "REGEX_DEFAULT_MATCH_TIMEOUT" property with the AppDomain.SetData method:

AppDomain.CurrentDomain.SetData("REGEX_DEFAULT_MATCH_
TIMEOUT",TimeSpan.FromMilliseconds(200));

Anyway, if we specify the matchTimeout parameter, we will override the global value.

Defining the culture for an application domain

With .NET 4.5, we have in our hands a way of specifying the default culture for all of our application threads in a quick and efficient way.

How to do it...

We will now define the default culture for our application domain as follows:

  1. Create a new Visual Studio project of type Console Application named caCultureAppDomain.
  2. Open the Program.cs file and add the using clause for globalization:

    using System.Globalization;

  3. Next, add the following methods:

    static void DefineAppDomainCulture() {
    String CultureString = "en-US";
    DisplayCulture();
    CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecif
    icCulture(CultureString);
    CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpec
    ificCulture(CultureString);
    DisplayCulture();
    Console.ReadLine();
    }
    static void DisplayCulture() {
    Console.WriteLine("App Domain........: {0}", AppDomain.
    CurrentDomain.Id);
    Console.WriteLine("Default Culture...: {0}", CultureInfo.
    DefaultThreadCurrentCulture);
    Console.WriteLine("Default UI Culture: {0}", CultureInfo.
    DefaultThreadCurrentUICulture);
    }

  4. Then add a call to the DefineAppDomainCulture() method.
  5. If we execute it, we will observe that the initial default cultures are null and we specify them to become the default for the App Domain.

How it works...

We used the CultureInfo class to specify the culture and the UI of the application domain and all its threads. This is easily done through the DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture properties.

There's more...

We must be aware that these properties affect only the current application domain, and if it changes we should control them.

Microsoft .NET Framework 4.5 Quickstart Cookbook Get up to date with the exciting new features in .NET 4.5 Framework with these simple but incredibly effective recipes with this book and ebook.
Published: May 2013
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

Overriding the default reflection behavior

One interesting capability of .NET 4.5 is that we can customize our refl ection context, overriding the default reflection behavior with the CustomReflectionContext class.

With it, we can control what properties and attributes are exposed by a class through reflection.

How to do it...

Here we will override the reflection behavior to provide additional attributes:

  1. Create a new Visual Studio project of type Console Application named caOverridingReflection.
  2. In the References folder of the project, in the Solution Explorer, add a reference to the System.Reflection.Context assembly.
  3. Open the Program.cs file and add a using clause for system.reflection.

    using System.Reflection;

  4. Next, add the SomeClass declaration:

    class SomeClass
    {
    //Nothing here..

    }

  5. Then add a method to visualize, through refl ection, the attributes of a type:

    public static void ShowAttributes(Type t)
    {
    foreach (Attribute a in t.GetCustomAttributes())
    {
    Console.WriteLine(a);
    }
    Console.ReadLine();
    }

  6. Call it from the Main method and the result should be none, that is, our class has no attributes so there is nothing to display on the console.
  7. Next, add a class with the name MyCustomReflectionContext.cs and add a reference to System.Reflection and System.Reflection.Context.

    using System.Reflection;
    using System.Reflection.Context;

  8. Change the generated code for the following one:

    class MyCustomReflectionContext :CustomReflectionContext
    {
    protected override IEnumerable<object>
    GetCustomAttributes(MemberInfo member, IEnumerable<object>
    declaredAttributes)
    {
    if (member == typeof(SomeClass)){
    List<object>CustomAttributes = new List<object>();
    CustomAttributes.Add
    (new DefaultMemberAttribute("One"));
    CustomAttributes.Add
    (new DefaultMemberAttribute("Two"));
    CustomAttributes.Add
    (new DefaultMemberAttribute("Three"));
    return base.GetCustomAttributes
    ( member, declaredAttributes);
    }
    }

  9. Change the ShowAttributes method as follows:

    public static void ShowAttributes(Type t)
    {
    foreach (Attribute a in t.GetCustomAttributes())
    {
    Console.WriteLine(a + " - " + (a as DefaultMemberAttribute).
    MemberName );
    }
    Console.ReadLine();
    }

  10. Finally, change the code in the Main method as follows so that we can test it properly:

    static void Main(string[] args)
    {
    Console.WriteLine("1. Without Custom Reflection Context");
    ShowAttributes(typeof(SomeClass));
    Console.WriteLine("2. With Custom Reflection Context");
    MyCustomReflectionContextCustRefCtx = new
    MyCustomReflectionContext();
    Type Mappedtype = CustRefCtx.MapType(typeof(SomeClass).
    GetTypeInfo());
    ShowAttributes(Mappedtype);
    }

  11. If we execute the code, we will get the result shown in the following screenshot:

How it works...

We used reflection to get the custom attributes of a type we just created and we got none.

Next, we created a CustomReflectionContext that will allow us to customize what is exposed through reflection. In our case, we are ensuring that if the class is our recently created class, it should return three DefaultMemberAttribute replies. If not, it will return the current attributes of the class.

To illustrate this reflection context, create an instance of the reflection context to map a concrete type, SomeClass in our case. We will now have this new mapped type created in the reflection context and thus affected by it.

Finally, we used reflection as we did previously but now we will get three new attributes that we did not get before.

There's more...

With .NET 4.5, we can customize the reflection output of types as we see fi t, as it is able to provide virtualized type information. This can be useful in many situations when we want more flexibility in providing type-driven behaviors or to dynamically change the properties that we want to make available.

We had TypeDescriptors and PropertyDescriptors before but they were not really a solution for design time, which CustomReflectionContext is.

A smart application of this would be to get the MEF to compose types that aren't MEF-enabled (that is, decorated with the MEF attributes). When constructing catalogs specifying ReflectionContext, MEF will project types through that reflection context and use the resulting view for its composition mechanism.

This next great application suggestion is from Mircea Trofin, from the CLR product team--thanks, Mircea!

Using the new ZipArchive class

We have two new classes, ZipArchive and ZipArchiveEntry, which add the capability to create .zip archives to the .NET framework. This was possible previously, but with several limitations.

How to do it...

Next we will see how to use the ZipArchive class to create a Zip file and to extract it to a concrete location.

  1. Create a new Visual Studio project of type Console Application named caZipArchive.
  2. Add the System.IO.Compression and System.IO.Compression.Filesystem assemblies as references to the project.
  3. Open the Program.cs file and add the following using clauses:

    using System.IO;
    using System.IO.Compression;

  4. Next, add the following method:

    static void CreateZipFile() {
    String ZipPath= @"C:\PACKT\02-CLR\caZipArchive\test\";
    String ZipFilePath = ZipPath + "test.zip";
    String FileName01 = "OneTextDocument.txt";
    String FileName02 = "OtherTextDocument.txt";
    String FileToZip01 = ZipPath + FileName01;
    String FileToZip02 = ZipPath + FileName02;
    using (FileStreamZipToOpen = new FileStream(ZipFilePath, FileMode.
    CreateNew))
    {
    using (ZipArchiveZArchive = new ZipArchive(ZipToOpen,
    ZipArchiveMode.Create))
    {
    ZArchive.CreateEntryFromFile(FileToZip01, FileName01);
    ZArchive.CreateEntryFromFile(FileToZip02, FileName02);
    }
    }
    }

  5. We should change the directory address and create the two files at the corresponding folder, just for testing purposes.
  6. Call it from the Main method and execute the application. We should see that a Zip file has been created for us.
  7. Delete the Zip File.
  8. Add the following method:

    static void ExtractZipFile() {
    String ZipPath = @"C:\PACKT\02-CLR\caZipArchive\test\";
    String ZipFilePath = ZipPath + "test.zip";
    String ExtractionPath = @"C:\PACKT\02-CLR\caZipArchive\test\
    unzip";
    using (ZipArchiveZArchive = ZipFile.OpenRead(ZipFilePath))
    {

    foreach (ZipArchiveEntry zaEntry in ZArchive.Entries)
    {
    zaEntry.ExtractToFile(Path.Combine(ExtractionPath,
    zaEntry.FullName));
    }
    }
    }

  9. And call it in the Main method, just after CreateZipFile:

    static void Main(string[] args)
    {
    //First we create the zip file
    CreateZipFile();
    //Next, we extract it
    ExtractZipFile();
    }

  10. Delete the previously generated ZIP file and create the unzip directory.
  11. If we execute the application, a ZIP file should be generated on the specified directory, and we should find all the files that we added in the extraction directory.

How it works...

We used FileStream to create a new file stream and write to it with ZipArchive.

Additionally, we added two files using the CreateEntryFromFile extension method of the ZipArchive class that is the result of adding the System.IO.Compression.FileSystem assembly.

With this we had our ZIP file created.

Continuing, we opened our ZIP file using the OpenRead method of the ZipFile class, which returns a ZipArchive object that represents the package of compressed files.

We can iterate all the entries with a simple for each instruction. For each ZipArchiveEntry, we extract it with the ExtractToFile extension method.

And that's it! In a few lines of code we have created a ZIP file, added some files, and then extracted the ZIP files to another folder.

There's more...

We could also specify the level of compression, edit the files within the ZIP file, or update existing ZIP files.

Additionally, for simplicity we 'neither validated for the existence of files or directories nor checked for any errors, so we should do this properly in a production environment.

We should be aware that the extension methods (provided by the System.IO.Compression. FileSystem assembly) that we used aren't available in Windows Store apps. There we should compress and decompress using the GZipStream or DeflateStream class.

Understanding async and await in .NET 4.5

The new asynchronous capabilities of .NET 4.5 rely on the async and await modifiers. Basically we have two important points here:

  • The async modifier indicates to the compiler that a method or lambda expression is asynchronous—we call them async methods.
  • The await operator, which can only be used within an async method, is applied to a task to suspend execution of the method until the task is complete. Meanwhile, the control is returned to the caller of that method.

How to do it...

Here we will use the async and await features in a basic way to clearly understand them.

  1. Create a new Visual Studio project of type Console Application named caAsyncAwait.
  2. Add a reference to the System.Net.Http assembly.
  3. In the Program.cs file, add the following using clauses:

    using System.Net;
    using System.IO;

  4. Next, add the following methods:

    Static async Task HttpTestAsync(String url) {
    byte[] result = await GetURLContentsAsync(url);
    Console.WriteLine("Received {0,8} bytes..", result.Length);
    }
    private static async Task<byte[]> GetURLContentsAsync(string url)

    {
    var content = new MemoryStream();
    var webReq = (HttpWebRequest)WebRequest.Create(url);
    using (WebResponse response = await webReq.GetResponseAsync())
    {
    using (Stream responseStream = response.GetResponseStream())
    {
    Await responseStream.CopyToAsync(content);
    }
    }
    Return content.ToArray();
    }

  5. Add a call to the HttpTestAsync function in the Main method surrounded with some sentences in the Console.Writeline method to keep track of what is happening:

    static void Main(string[] args)
    {
    Console.WriteLine("Start of Main Method");
    HttpTestAsync("http://www.packtpub.com/forthcoming-titles");
    Console.WriteLine("End of Main Metod");
    Console.ReadLine();
    }

  6. We should execute the application and get the results shown in the following screenshot:

  7. Next, add the following method:

    Static async void MultipleHttpTestAsync()
    {
    Task t1 = HttpTestAsync("http://www.packtpub.com/forthcoming-
    titles");
    Task t2 = HttpTestAsync("http://www.silverlightguy.com");
    Task t3 = HttpTestAsync("http://www.microsoft.com");

    await t1;
    await t2;
    await t3;
    Console.WriteLine("All tasks have finished..");
    }

  8. Comment the previous call to HttpTestAsync in the Main method and next to it add a call to MultipleHttpTestAsync.
  9. If we execute the code, we will see that the different tasks are executed after the Main method ends. If we execute it several times, their finishing order might change.

  10. Now, we will add a similar method:

    Static async void OptimizedMultipleHttpTestAsync()
    {
    Task t3 = HttpTestAsync("http://www.packtpub.com/forthcoming-
    titles");
    Task t2 = HttpTestAsync("http://www.silverlightguy.com");
    Task t1 = HttpTestAsync("http://www.microsoft.com");
    Task[] tasklist= new Task[] { t1, t2, t3 };
    Await Task.WhenAll(tasklist);
    Console.WriteLine("All tasks have finished..");
    }

  11. Then we will change the call from the Main method to this new method.
  12. If we execute it, we get practically the same output as with the previous code.

How it works...

We have initially created the HttpTestAsync method, adding to it the async modifier, which indicates that the method (or the lambda expression) is asynchronous. These methods are called async methods.

An async method provides the ability to be called without blocking the caller's thread, which is convenient for long-running jobs. Also, the caller of an async method resumes its work without waiting for the async method to finish, unless we indicate in the call to the async method that we wish to wait until it finishes; we will do that with the await expression.

The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task is completed. Basically, it waits for the completion of the task. Nowadays, the thread is not blocked and the process continues, but the rest of the code after the await operator becomes an automatic callback method.

It is obvious that the task where the await operator is applied must be modified by the async modifier and returns a task or task of TResult, that is, when the task is returned by an async method, it might not be the source of the task.

Additionally, by convention, all asynchronous method names should end in Async.

Going back to the HttpTestAsync method we just commented, we have marked it as async and it is returning a task that we can wait for with the await operator. Inside it, because it is an async method, it can await the completion of the GetURLContentsAsync method.

The GetURLContentsAsync method is an async method that retrieves a URL with a WebRequest method, gets its content as a response, and returns it when it is finished.

HttpTestAsync takes the resultant content from GetURLContentsAsync as we are waiting for it to finish with await and writes on the console the total amount of bytes received.

We execute the first test with the following lines of code:

Console.WriteLine("Start of Main Method");
HttpTestAsync("http://www.packtpub.com/forthcoming-titles");
Console.WriteLine("End of Main Metod");

We continue with the Main method before the awaited GetURLContentsAsync method finishes so that the main console writelines are written first.

In the next example we code, MultipleHttpTestAsync, we are creating three tasks to download three URLs asynchronously and then we await them. The tasks are being executed in parallel since they are started at creation. The await expression only indicates that the processing can't continue until the task finishes.

So with this code, we really are controlling the start time of the tasks (that is, the async methods are called) but not their end time. The order of the await operators can affect the times a bit but they might finish before arriving at the await expressions:

Task t3 = HttpTestAsync("http://www.packtpub.com/forthcoming-titles");
Task t2 = HttpTestAsync("http://www.silverlightguy.com");
Task t1 = HttpTestAsync("http://www.microsoft.com");
await t1;
await t2;
await t3;

A more elegant solution is what we will do in the next example, where we add all the tasks to an array and use the Task.WhenAll method on this generated collection of tasks:

Task[] tasklist = new Task[] { t1, t2, t3 };
await Task.WhenAll(tasklist);

This method asynchronously awaits multiple asynchronous operations that it expects as an IEnumerable of tasks.

This way the code will resume when all the tasks have been completed, not before or after.

There's more...

We have seen the basics of async and await, explored task handling, and even executed some the tasks in parallel. We ended up using a method from the Task class, WhenAll, which enabled us to wait for a list of tasks to finish.

But there is a lot more to explore with task management, which you will be familiar with if you have already explored the TPL. We have plenty of options there to control the processing flow of our application in ways that would have been extremely complicated earlier.

Using the new asynchronous file I/O operations

There are some brand new asynchronous methods for file operation I/O, which are clearly designed for providing resource-intensive work without blocking the main UI thread.

For I/O operations, we have some interesting methods such as ReadAsync, WriteAsync, CopyToAsync, FlushAsync, ReadLineAsync, and ReadToEndasync, which are implemented on stream classes and on classes that read and/or write to streams such as TextWriter or TextReader.

How to do it...

Next we will see a simple example that we can extrapolate to a majority of these methods with ease.

  1. Create a new Visual Studio project of type Console Application named caAsyncIO.
  2. Add a using clause for System.IO:

    using System.IO;

  3. Copy the following base method:

    Private async static void CopyFolderContents() {
    String SourceFolder = @"C:\PACKT\02-CLR\caAsyncIO\source";
    String DestinationFolder = @"C:\PACKT\02-CLR\caAsyncIO\
    destination";
    Console.WriteLine("Going to copy {0} files..", Directory.
    EnumerateFiles(SourceFolder).Count());
    foreach (string SourceFile in Directory.
    EnumerateFiles(SourceFolder))
    {
    String DestinationFile = DestinationFolder + SourceFile.
    Substring(SourceFile.LastIndexOf('\\'));
    Await CopyFilesWithFileStreams(SourceFile,
    DestinationFile);
    }
    }

  4. Then call it from the Main method:

    static void Main(string[] args)
    {
    CopyFolderContents();
    Console.ReadLine();
    }

  5. We just need to add the CopyFilesWithFileStreams method:

    Private async static Task CopyFilesWithFileStreams(StringStartFi
    le, String DestinationFile)
    {
    using (FileStreamSourceFileStream = File.Open(StartFile,
    FileMode.Open))
    {
    using (FileStreamDestinationFileStream = File.
    Create(DestinationFile))
    {
    Await SourceFileStream.CopyToAsync(DestinationFileStream);
    Console.WriteLine("Copied the " + DestinationFile);
    }
    }
    }

  6. Then we can execute the FileStream I/O test. The execution of our application should give us the following result:

  7. We will add the following two methods to implement a stream version of what we just did:

    Private async static Task CopyFilesWithStreams(String StartFile,
    String DestinationFile) {
    using (StreamReader SourceStreamReader = File.OpenText(StartFile))
    {
    using (StreamWriter DestinationStreamWriter = File.
    CreateText(DestinationFile))
    {
    Await CopyFilesAsync(SourceStreamReader,
    DestinationStreamWriter);
    Console.WriteLine("Copied the " + DestinationFile);
    }
    }
    }
    Public async static Task CopyFilesAsync(StreamReader SourceReader,
    StreamWriter DestinationWriter)
    {
    char[] buffer = new char[0x1000];
    int numRead;
    while ((numRead = await SourceReader.ReadAsync(buffer, 0,
    buffer.Length)) != 0)
    {
    Await DestinationWriter.WriteAsync(buffer, 0, numRead);
    }
    }

  8. We will only need to modify the CopyFolderContents() method by commenting the call to CopyFilesWithFileStreams and adding a call to CopyFilesWithStreams:

    await CopyFilesWithStreams(SourceFile, DestinationFile);

  9. If we execute it, the result will be exactly the same as before.

How it works...

We have set up a system to copy all the files from one directory to another. Using the Directory.EnumerateFiles method does the trick, and we just have to enumerate them and delegate the task to a copy method with source and destination paths that include the filename.

Additionally, CopyFolderContents has been declared async so we can use the await operator inside it, and we do that with CopyFilesWithStreams, the first method we implement to read and copy the file using FileStream objects. We do it with nested using, the first for opening the file with File.Open and the second for creating and writing the destination file with File.Create.

Finally we use the CopyToASync asynchronous method to do the trick. Of course, we use the await operator inside it.

Next, we implement the same functionality but with the StreamReader and StreamWriter objects. We do it in a similar way, that is, with the two nested using clauses, one for the reader and the other for the writer.

For executing the reading and writing tasks, we implemented our own method that executes a while loop that reads and writes a buffer from the source stream into the destination stream until it finishes copying. For doing this, it uses the new ReadAsync and WriteAsync methods.

There's more...

We have seen how to use some of the many available methods, and there are many more to explore, but anyway, the concepts and workings are similar to those we have just seen.

Summary

In this article we covered various recipes to explore the new features of CLR. In this article we have focused on the essential recipes such as Creating a portable library, Controlling the timeout in regular expressions, Defining the culture for an application domain, Overriding the default reflection behavior, Using the new ZipArchive class, Understanding async and await in .NET 4.5, and Using the new asynchronous file I/O operations, in order to showcase what is best suited for your requirements.

Resources for Article:


Further resources on this subject:


Microsoft .NET Framework 4.5 Quickstart Cookbook Get up to date with the exciting new features in .NET 4.5 Framework with these simple but incredibly effective recipes with this book and ebook.
Published: May 2013
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


Jose Luis Latorre Millas

Jose Luis Latorre Millas is a Microsoft Silverlight MVP, Toastmaster's Competent Communicator, TechEd speaker, INETA speaker, STEP member, trainer, technical writer, and reviewer. He is deeply involved with the technical communities through his collaboration with INETA Europe, Barcelona Developers, and other communities and user groups. He recently co-founded the Zurich .NET Developers user group at Zurich, Switzerland, which can be found at http://ZurichDev.net.

Jose Luis Latorre is strongly focused on XAML technologies such as Windows Store Apps, Windows Phone Apps, Silverlight, and WPF. He has written several articles on these topics, reviewed books, and worked with and given several talks over the last few years on these areas of knowledge.

Jose Luis works as UI Team Lead developer at Roche Diagnostics, where he does his best to develop and improve diagnostic software and its interfaces, which will help to save lives.

Books From Packt


.Net Framework 4.5 Expert Programming Cookbook
.Net Framework 4.5 Expert Programming Cookbook

Ext.NET Web Application Development
Ext.NET Web Application Development

.NET 4.0 Generics Beginner’s Guide
.NET 4.0 Generics Beginner’s Guide

 WCF 4.5 Multi-Layer Services Development with Entity Framework
WCF 4.5 Multi-Layer Services Development with Entity Framework

 WCF 4.0 Multi-tier Services Development with LINQ to Entities
WCF 4.0 Multi-tier Services Development with LINQ to Entities

DotNetNuke 5.4 Cookbook
DotNetNuke 5.4 Cookbook

.NET Compact Framework 3.5 Data Driven Applications
.NET Compact Framework 3.5 Data Driven Applications

 Microsoft Visual Studio LightSwitch Business Application Development
Microsoft Visual Studio LightSwitch Business Application Development


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Y
R
m
Q
u
b
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software