Learn the best practices to create and schedule tasks efficiently in .Net using Task.Run and Task.Factory.StartNew methods When creating tasks using Task.Factory.StartNew or Task.Run methods, you should keep certain important points in mind when writing asynchronous code. In most cases, it is advisable to avoid using Task.Factory.StartNew method if you are working with asynchronous code. If you are working with parallel code, I would say that StartNew is a good choice. A task scheduler is a component that is responsible for scheduling tasks; The .Net framework provides you with two task schedulers. There’s the default task scheduler that runs on the .Net framework thread pool, and there’s the task scheduler that executes on the synchronization context of a specified target. The default task scheduler will suffice most of the time, but you can also build your own custom task scheduler to provide added functionalities. To build your own custom task scheduler you would need to create a class that extends the System.Threading.Tasks.TaskScheduler class. How do I create Tasks using the Task Parallel Library? There are several ways in which you can create and start tasks in .Net. You need to make use of the System.Threading.Tasks.Task or System.Threading.Tasks.Task class to create tasks (a schedulable unit of work). While the former is used to create a task that doesn’t return a value, the latter is used to create tasks that have return values. The Task.Factory property is an instance of the TaskFactory class. This property is used to create and schedule tasks. While the Task.Factory.StartNew method works like a fork operation and is used to create and start new tasks, the Wait method works just like a join operation and waits for the task to be complete. The following code snippet illustrates how you can use the Task.Factory.StartNew method. Task.Factory.StartNew(() => TestMethod(), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); You can also create a Task using the Task.Run method as shown in the code snippet below. public async Task DoSomeWork() { await Task.Run(() => TestMethod()); } void TestMethod() { Console.WriteLine("Hello world!"); } If you would like to return a value from a Task you can take advantage of Task.FromResult method as shown in the code snippet below. public async Task DoSomeWork() { string text = await Task.FromResult<string>(GetMessage()); } private string GetMessage() { return "Hello world!"; } You can also create tasks using a delegate or an action. The following code snippet shows how you can create tasks using actions and delegates. Task task1 = new Task (new Action(Display)); task1.Start(); Task task2 = new Task (delegate { Display(); }); task2.Start(); You can also create tasks using lamba and anonymous methods. Task.Factory.StartNew and Task.Run Task.Factory.StartNew is a quick way of creating and starting a Task. Note that a call to Task.Factory.StartNew is functionally equivalent to creating a task instance and then calling the Start method on the instance. However, it is not recommended to be used for reasons aplenty. If you would like to execute synchronous code, Task.Factory.StartNew is not a good choice. Note that if a task scheduler is available, the StartNew method will execute the task on that task scheduler. On the contrary, if a scheduler isn’t available, it would execute the task on a thread pool thread. It should be noted that Task.Factory.StartNew defaults to TaskScheduler.Current and not TaskScheduler.Default. Note that a call to Task.Run(action) is equivalent to the following statement: Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); On the contrary, a call to Task.Factory.StartNew(action) is equivalent to the following statement: Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Current); If may want to use Task.Factory.StartNew if you have created a custom task scheduler and pass the scheduler instance to it explicitly. I would always recommend using Task.Run as it is much simpler and has safer defaults. In other words, we should avoid using Task.Factory.StartNew unless there is a need to create a task scheduler and then pass it explicitly when calling the StartNew method to create a new task and schedule it. If you were to use the TaskFactory.StartNew method effectively and reliably, you should use a custom task scheduler and then specify the CancellationToken and TaskCreationOptions. The Task.Run method is recommended to use when you don’t need to have much fine-grained control over thread scheduling and its intricacies. You should use Task.Run primarily on CPU bound methods. However, you should use Task.Run while invoking the task and not inside the implementation of the task. In other words, you should use Task.Run not inside any implementation of a method but at the point where the method is called. As an example, the following code snippet is an example of a “bad” piece of code. public async Task<string> DownloadDataFromWebAsync(Uri uri) { return await Task.Run(() => { using (WebClient webClient = new WebClient()) { return webClient.DownloadString(uri); } }); } Refer to the code snippet given above. The method isn’t scalable as it would block the background thread, retrieve a thread from the thread pool and execute synchronously on it. Hence, it would consume more resources in your system. Related content feature What is Rust? Safe, fast, and easy software development Unlike most programming languages, Rust doesn't make you choose between speed, safety, and ease of use. Find out how Rust delivers better code with fewer compromises, and a few downsides to consider before learning Rust. By Serdar Yegulalp Nov 20, 2024 11 mins Rust Programming Languages Software Development how-to Kotlin for Java developers: Classes and coroutines Kotlin was designed to bring more flexibility and flow to programming in the JVM. Here's an in-depth look at how Kotlin makes working with classes and objects easier and introduces coroutines to modernize concurrency. By Matthew Tyson Nov 20, 2024 9 mins Java Kotlin Programming Languages analysis Azure AI Foundry tools for changes in AI applications Microsoft’s launch of Azure AI Foundry at Ignite 2024 signals a welcome shift from chatbots to agents and to using AI for business process automation. By Simon Bisson Nov 20, 2024 7 mins Microsoft Azure Generative AI Development Tools news Microsoft unveils imaging APIs for Windows Copilot Runtime Generative AI-backed APIs will allow developers to build image super resolution, image segmentation, object erase, and OCR capabilities into Windows applications. By Paul Krill Nov 19, 2024 2 mins Generative AI APIs Development Libraries and Frameworks Resources Videos