What are tasks in C#?

Let’s dive deeper into the stages of a Task and its internal mechanisms, including synchronization and joining.

In C#, a Task represents an asynchronous operation that can be scheduled and executed independently. It provides a higher-level abstraction for concurrent and parallel programming. Behind the scenes, Task utilizes threads from the underlying thread pool to execute the asynchronous code.

A Task goes through several stages during its lifecycle:

  1. Created: When you create a Task instance, it is in the created state. At this stage, the task is not scheduled for execution.

  2. Scheduled: Once you schedule the task for execution, it enters the scheduled state. The task scheduler is responsible for determining when and how the task will be executed.

  3. Running: When the task is actively executing its code, it is in the running state. The underlying thread pool assigns a thread to execute the task’s workload.

  4. Completed: After the task’s code execution finishes, it transitions to the completed state. At this point, the task has produced a result or completed its operation.

  5. Canceled: If the task is canceled before completion, it moves to the canceled state. Cancellation is typically initiated by the user or by some external condition.

  6. Faulted: If an unhandled exception occurs during the task’s execution, it enters the faulted state. This state indicates that the task encountered an error or exception.

Now, let’s modify our previous example to include additional stages and demonstrate how Task progresses through them:

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {
        // Create a task that simulates a time-consuming operation
        Task<int> task = Task.Run(() => DoWork("Task", 5000));

        Console.WriteLine("Task created and scheduled.");

        // Check the task's status
        Console.WriteLine($"Task status: {task.Status}");

        // Wait for the task to complete
        task.Wait();

        // Check the task's status again
        Console.WriteLine($"Task status: {task.Status}");

        // Get the task's result
        int result = task.Result;
        Console.WriteLine($"Task result: {result}");

        // Continue with other code after the task completes
        Console.WriteLine("Task completed. Proceeding with other code.");
    }

    private static int DoWork(string taskName, int duration)
    {
        Console.WriteLine($"{taskName} started.");
        Thread.Sleep(duration);
        Console.WriteLine($"{taskName} completed.");
        return 42;
    }
}
MainTaskDoWorkTask.Run(DoWork)DoWork("Task", 5000)Thread.Sleep(duration)Task  status: WaitingForActivationTask is running asynchronouslytask.Wait()Task  status: RanToCompletionint result = task.ResultTask  result: 42Task completed. Proceeding with other codeMainTaskDoWork

In this example, we added additional stages and status checks to illustrate the lifecycle of a Task. The DoWork method still represents a time-consuming operation, but now it returns an integer result.

When you run the program, you’ll observe the following output:

Task created and scheduled.
Task status: WaitingForActivation
Task started.
Task completed.
Task status: RanToCompletion
Task result: 42
Task completed. Proceeding with other code.

Using thread

To achieve the same functionality using Thread in C#

using System;
using System.Threading;

public class Program
{
    public static void Main()
    {
        // Create a new thread and pass the DoWork method as a delegate
        Thread thread = new Thread(() => DoWork("Thread", 5000));

        Console.WriteLine("Thread created.");

        // Start the thread
        thread.Start();

        // Check the thread's status
        Console.WriteLine($"Thread status: {thread.ThreadState}");

        // Wait for the thread to complete
        thread.Join();

        // Check the thread's status again
        Console.WriteLine($"Thread status: {thread.ThreadState}");

        Console.WriteLine("Thread completed. Proceeding with other code.");
    }

    private static void DoWork(string threadName, int duration)
    {
        Console.WriteLine($"{threadName} started.");
        Thread.Sleep(duration);
        Console.WriteLine($"{threadName} completed.");
    }
}
Next Post Previous Post
No Comment
Add Comment
comment url