Take advantage of the async and await keywords in C# to implement asynchronous file operations You can take advantage of asynchrony to perform resource-intensive I/O operations sans the need to block the main or the executing thread of the application. Asynchrony when used properly can increase the responsiveness and scalability of your applications to a considerable extent. This article presents an overview on asynchronous file operations using C#. Why is asynchrony needed? Asynchronous programming enables you to execute tasks separate from the main application thread, then notifies the thread when its execution is over. Asynchrony helps you execute tasks sans the need of holding up the execution flow or responsiveness of your application. You can leverage asynchrony to improve the performance and responsiveness of your application as the calling thread can continue to perform other operations while the method that can been called asynchronously continues to execute. The async and await keywords If you were to use .Net Framework and its earlier versions, you could leverage the BeginRead() and the EndRead() methods to implement asynchronous operations when working with files. Although these methods are still available as part of the newer versions of the .Net Framework, you can use the two new keywords async and await that have been introduced as part of .Net Framework 4.5. Hence, you can take advantage of async and await to implement asynchronous file operations when working with .Net Framework 4.5 or later. You can learn more about async and await on MSDN. In using asynchrony you can make the user interface threads more responsive and perform other activities while the asynchronous operation is in progress. Performing asynchronous file operations You can use the FileStream class to perform asynchronous I/O operations. In most cases, this would ensure that the calling thread is not blocked while the asynchronous file operation is in progress. To use this option, you should turn on the asynchronous option (with the option useAsync: true) when creating an instance of the FileStream class. This is shown in the code snippet given below. FileStream fileStream = new FileStream("C:IDG.txt", FileMode.Append, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true); The following method writes a text passed to it as parameter to a file asynchronously. Note the usage of the await keyword when calling the WriteAsync() method and the async keyword that is used in the method signature to imply this method would have one or more await statements. static async Task WriteToFileAsync(string filePath, string text) { if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath"); if (string.IsNullOrEmpty(text)) throw new ArgumentNullException("text"); byte[] buffer = Encoding.Unicode.GetBytes(text); Int32 offset = 0; Int32 sizeOfBuffer = 4096; FileStream fileStream = null; try { fileStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None, bufferSize: sizeOfBuffer, useAsync: true); await fileStream.WriteAsync(buffer, offset, buffer.Length); } catch { //Write code here to handle exceptions. } finally { if(fileStream != null) fileStream.Dispose(); } } It should be noted that if you don’t include the await keyword inside an asynchronous method, the entire method would execute synchronously. Note that the usage of async and await doesn’t create any additional threads. The following code snippet illustrates how you can call the WriteToFileAsync() method from the Main() method to write a text asynchronously. static Task WriteToFile() { string filePath = "C:IDG.txt"; string text = "Hello Worldrn"; return WriteToFileAsync(filePath, text); } static void Main(string[] args) { WriteToFile().Wait(); Console.Write("Press any key to exit... "); Console.ReadKey(); } The following method reads text from a file asynchronously. You would need to pass the file name and the size of the buffer as parameters. Note how the object readBuffer is set to null in the catch block if an exception occurs so that the caller method can identify if an exception has occurred while attempting to read text from the file. static async Task<string> ReadFromFileAsync(string filePath, int bufferSize) { if (bufferSize < 1024) throw new ArgumentNullException("bufferSize"); if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath"); StringBuilder readBuffer = null; byte[] buffer = new byte[bufferSize]; FileStream fileStream = null; try { readBuffer = new StringBuilder(); fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: bufferSize, useAsync: true); Int32 bytesRead = 0; while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length)) > 0) { readBuffer.Append(Encoding.Unicode.GetString(buffer, 0, bytesRead)); } } catch { readBuffer = null; //Write code here to handle exceptions; } finally { if (fileStream != null) fileStream.Dispose(); } return readBuffer.ToString(); } Note that we have used the FileStream class in the code examples presented in this post as StreamReader and StreamWriter doesn’t provide support for asynchronous read and write operations. You can invoke the ReadFromFileAsync() method from the following method. Note that the ReadFromFile() method given below returns a Task<string> object. static async Task<string> ReadFromFile() { string filePath = "C:IDG.txt"; return await ReadFromFileAsync(filePath, 4096); } You can now call the ReadFromFile() method from the Main() method to retrieve and display all text from the file in the console window. <span style="line-height: 1.75em;">static void Main(string[] args)</span> { string text = ReadFromFile().Result; Console.Write(text); Console.ReadKey(); } Related content how-to How to use FastEndpoints in ASP.NET Core Take advantage of the free open-source FastEndpoints library to build fast and lean APIs in your ASP.NET Core applications. By Joydip Kanjilal Jul 11, 2024 7 mins Microsoft .NET C# Development Libraries and Frameworks how-to How to use Refit to consume APIs in ASP.NET Core Take advantage of Refit REST library to simplify API consumption and make your code cleaner, more efficient, and easier to maintain. By Joydip Kanjilal Jul 04, 2024 10 mins C# Microsoft .NET Software Deployment how-to When to use an abstract class vs. interface in C# Understanding the differences between an abstract class and interface is key to designing loosely coupled and extensible applications. By Joydip Kanjilal Jun 20, 2024 10 mins Small and Medium Business Microsoft .NET C# how-to 6 security best practices for ASP.NET Core Learn the best practices and built-in safeguards for preventing attacks and protecting sensitive data in your ASP.NET Core web applications. By Joydip Kanjilal Jun 07, 2024 6 mins C# Microsoft .NET Web Development Resources Videos