Multithreading in CSharp With More Code
Multithreading in CSharp With More Code
What is Multithreading?
• Multithreading allows concurrent execution of
code.
• Threads are lightweight processes.
• Improves efficiency, especially in multi-core
CPUs.
Thread Class in C#
• Example using Thread class:
• using System.Threading;
void PrintNumbers() {
for (int i = 0; i < 5; i++) {
Console.WriteLine(i);
}
}
Thread t = new Thread(PrintNumbers);
t.Start();
Thread Lifecycle
• Thread lifecycle includes Unstarted → Running
→ WaitSleepJoin → Stopped.
• Thread t = new Thread(() =>
Thread.Sleep(1000));
Console.WriteLine(t.ThreadState); // Unstarted
t.Start();
Console.WriteLine(t.ThreadState); // Running
Thread Synchronization
• Use lock to avoid race conditions:
• object lockObj = new object();
int counter = 0;
void Increment() {
lock(lockObj) {
counter++;
}
}
Thread Safety
• Use locking or thread-safe collections:
• ConcurrentDictionary<int, string> dict = new();
dict.TryAdd(1, "value");
ThreadPool in C#
• Efficient management of threads using
ThreadPool:
• ThreadPool.QueueUserWorkItem(state => {
Console.WriteLine("Running in thread
pool.");
});
Tasks vs Threads
• Tasks provide simpler and more flexible thread
handling:
• Task task = Task.Run(() => {
Console.WriteLine("Task running...");
});
task.Wait();
Async and Await - Deep Explanation
• Async methods allow non-blocking operations.
Await pauses execution until result is ready.
• async Task DownloadFileAsync() {
HttpClient client = new HttpClient();
string content = await
client.GetStringAsync("http://example.com");
Console.WriteLine(content);
}
Best Practices in Multithreading
• Use async/await for I/O, avoid blocking. Use
ConfigureAwait(false) in libraries.
• async Task SaveAsync() {
await File.WriteAllTextAsync("file.txt",
"data").ConfigureAwait(false);
}
Thread Synchronization - Race Condition Fix
• Example showing proper synchronization with multiple threads:
• int counter = 0;
object lockObj = new object();
void Increment() {
for (int i = 0; i < 1000; i++) {
lock (lockObj) {
counter++;
}
}
}
task2.Wait();
Task Class - Returning Values
• Tasks can return values using generics:
• Task<int> computeTask = Task.Run(() => {
return 42;
});
// Using Task
Task task = Task.Run(() => Console.WriteLine("Task
running"));
task.Wait();