| C# Threading QA-1-10 :👈 | 👉:C# Threading QA-21-30 |
Dot net Framework (C#) Threading Question Answers - 11-20 |
11. Explain synchronization primitives for controlling the interactions of threads and avoiding race conditions.
Synchronization primitives can be roughly divided into three categories:
- Locking: lock, Monitor, Mutex, etc.
- Signaling: Join, WaitHandles, etc.
- Interlocked operations: atomic operations using
Interlockedclass (e.g., Add, Increment, Exchange, CompareExchange).
12. Example for joining the ThreadPool via asynchronous delegates
// Enter the thread pool via asynchronous delegates
static void Main()
{
Func<string, int> method = DoWork;
IAsyncResult cookie = method.BeginInvoke("From Asynchronous delegates", null, null);
// ...Do other work here in parallel
int result = method.EndInvoke(cookie);
Console.WriteLine("String length: " + result);
}
static int DoWork(string s)
{
return s.Length;
}
// Output
// String length: 27
13. Example for joining the ThreadPool via BackgroundWorker
using System.ComponentModel;
using System.Threading;
class BackgroundWorkerEx
{
static BackgroundWorker _bw = new BackgroundWorker();
static void Main()
{
int worker = 0, io = 0;
ThreadPool.GetAvailableThreads(out worker, out io);
Console.WriteLine("Total Threads in the Pool: -> " + worker + ", IO thread-> " + io);
_bw.DoWork += bw_DoWork;
_bw.RunWorkerAsync("Message to worker");
Console.ReadLine();
}
static void bw_DoWork(object sender, DoWorkEventArgs e)
{
int worker = 0, io = 0;
ThreadPool.GetAvailableThreads(out worker, out io);
Console.WriteLine("Remaining Threads: -> " + worker + ", IO thread-> " + io);
Console.WriteLine(e.Argument); // "Message to worker"
}
}
// Output
// Total Threads in the Pool: -> 3200, IO thread-> 3200
// Remaining Threads: -> 3198, IO thread-> 3200
// Message to worker
14. Example for joining the ThreadPool via Task Parallel Library (TPL)
using System.Threading;
using System.Threading.Tasks;
class ProgramThreadPool
{
static void Main()
{
int worker = 0, io = 0;
ThreadPool.GetAvailableThreads(out worker, out io);
Console.WriteLine("Total Threads in the Pool: -> " + worker + ", IO thread-> " + io);
Task.Factory.StartNew(DoWork);
}
static void DoWork()
{
int worker = 0, io = 0;
ThreadPool.GetAvailableThreads(out worker, out io);
Console.WriteLine("Remaining Threads: -> " + worker + ", IO thread-> " + io);
Console.WriteLine("Hello from the thread pool!");
}
}
// Output
// Total Threads in the Pool: -> 3200, IO thread-> 3200
// Remaining Threads: -> 3199, IO thread-> 3200
// Hello from the thread pool!
15. How to fix race conditions
- Use locking mechanisms: C# provides mechanisms like lock statements, Mutex, Semaphore, and Monitor to synchronize access to shared resources. These mechanisms ensure that only one thread can access the critical section of code at a time, preventing race conditions.
- Use atomic operations:
InterlockedThe System.Threading.Interlocked class provides atomic operations that can be used to perform operations like incrementing, decrementing, or exchanging values without the risk of race conditions. - Use concurrent collections: The System.Collections.Concurrent namespace provides thread-safe collection classes that handle synchronization internally, making it easier to work with shared data in a multi-threaded environment.
16. How to get the current Thread?
Use Thread.CurrentThread property.
17. How to pass data to a thread?
To pass arguments to a thread’s target method is to execute a lambda expression that calls the method with the desired arguments:
static void Main()
{
Thread t = new Thread(() => Print("Hello from t!"));
t.Start();
}
static void Print(string message)
{
Console.WriteLine(message);
}
18. How to prevent deadlock?
- Consistent locking order: Always acquire locks in the same order to avoid circular dependencies.
- Timeout mechanism (e.g., Monitor.TryEnter): Implement a timeout when acquiring a lock, so a thread doesn't wait indefinitely.
- Resource hierarchy: Define a hierarchy of resources and acquire locks according to that hierarchy.
- Use higher-level synchronization (e.g., ReaderWriterLockSlim):Employ constructs like Monitor.TryEnter with a timeout or use ReaderWriterLockSlim which provides more sophisticated synchronization options.
19. Does a blocked thread consume CPU resources?
No, a blocked thread does not consume CPU resources.
20. Important Thread Methods
- Start: Begins execution.
- Sleep: Pauses execution for a time.
- Suspend: Pauses a thread (deprecated).
- Abort: Stops a thread (deprecated).
- Resume: Restarts a suspended thread (deprecated).
- Join: Waits for a thread to finish.
| C# Threading QA-1-10 :👈 | 👉:C# Threading QA-21-30 |