A deadlock is a program state in which execution flows wait forever for progress that cannot occur. The classic case has one thread holding mutex A while waiting for mutex B, and another holding B while waiting for A. Deadlocks can also involve rings of several threads, a thread waiting for itself, shared resources, or a UI thread. section 4.2.4 section 7.3
Reduce deadlock risk with disciplined ownership and waiting:
- Use private lock objects so external code cannot unexpectedly acquire the same lock. section 4.2.4
- Acquire multiple locks in one consistent global order; the chosen order matters less than applying it everywhere. section 7.3
- Avoid raising callbacks or events while holding locks, because the callback can attempt to acquire another lock already held by the caller. section 7.3
- Do not use Thread.Suspend, Thread.Resume, or Thread.Abort to control work; suspension can occur while runtime code holds a lock needed by the thread that must resume it. section 4.2.4
- Treat lock, Mutex, Semaphore, and exclusive file access differently: some permit recursive acquisition, while others block or fail on another acquisition attempt. section 7.3
Asynchronous camera operation
A synchronous camera method acquires the camera, takes a picture, and releases it. Calling TakePictureAsync without awaiting it releases the camera too early. Making the method async and awaiting the operation preserves the required sequence. Replacing await with Task.Wait() or Task.Result can introduce deadlocks and removes the benefit of asynchronous execution. section 6.3.1
Figure 4.2 Deadlock that occurs when one thread has locked mutex A and is waiting for mutex B, while another thread has locked mutex B and is waiting for mutex A. This creates a situation where thread A is dependent on thread B to finish, but thread B is also dependent on thread A, which leads to an endless cycle of waiting.
Visualize the two-thread cycle: each thread owns one mutex and waits for the other, so neither can finish. section 4.2.4














