I am trying to write a unit test that can hit a piece of threaded code 100% of the time for code coverage. The code can ONLY be reached in the context of a threaded application, and is engineered to be hit only once for every object instance in order to minimize lock time expense.
As a simplified example:
public class Example
{
private readonly object lockObject = new object();
private int? objectToInit = null;
public void EnsureObjectInit()
{
//To minimize hitting the lock code, the object is checked first.
if (!objectToInit.HasValue)
{
lock (lockObject)
{
//Then it is checked once more to ensure that it wasn't initiazlized
//before the lock was hit.
if (objectToInit.HasValue)
{
//This block can only be executed if a second thread is able to
//get to the lock before the first can initialize the object.
return;
}
objectToInit = 0;
}
}
}
}
To get code coverage to hit the code inside the second if statement, I've tried code like this:
[TestClass]
public class ExampleTest
{
[Test Method]
public void async MyTest()
{
Example example = new Example();
void runTask()
{
example.EnsureObjectInit();
}
//I've tried increasing the number of threads, but it doesn't make
//it hit the noted code any more consistently.
List<Task> tasks = new List<Task>(2);
tasks.Add(Task.Run(runTask));
tasks.Add(Task.Run(runTask));
await Task.WhenAll(tasks);
... perform extra validation ...
}
}
But code coverage fails to reach the inner if block at least 50% of the time.
Is there any way to force the unit tested code to stop the first thread before initializing the object so that the second thread can get into the first "if" block?
It's a bit of a hack, but you could use reflection to get the lockObject from the Example class instance. Then lock it manually in the ExampleTest method. NOTE: this is a highly couple test. If you change the name of the lock the test will fail.
private class LockExample
{
private readonly object lockObject = new object();
public void TestLock()
{
lock(lockObject)
{
//Do something
}
}
}
private class LockTest
{
public void Test()
{
var example = new LockExample();
var lockOjbect = typeof(LockExample).GetField("lockObject", BindingFlags.NonPublic|BindingFlags.Instance).GetValue(example);
lock (lockOjbect)
{
var task = Task.Run((Action)example.TestLock);
task.Wait(1); //allow the other thread to run
}
}
}
With a slight design change you can make your code easier testable: Extract the access to objectToInit.HasValue into a helper method like hasObjectToInitValue(). In your test, you can then override that method and can then test the scenario that the helper method on first call returns false and on second returns true.
Related
here's my question:
Say I have this program (I'll try to semplify as much as I can):
receiveResultThread waits for result from differents network clients, while displayResultToUIThread updates the UI with all the results received.
class Program
{
private static Tests TestHolder;
static void Main(string[] args)
{
TestHolder = new Tests();
Thread receiveResultsThread = new Thread(ReceiveResult);
receiveResultsThread.Start();
Thread displayResultToUIThread = new Thread(DisplayResults);
displayResultToUIThread.Start();
Console.ReadKey();
}
public static void ReceiveResult()
{
while (true)
{
if (IsNewTestResultReceivedFromNetwork())
{
lock (Tests.testLock)
TestHolder.ExecutedTests.Add(new Test { Result = "OK" });
}
Thread.Sleep(200);
}
}
private static void DisplayResults(object obj)
{
while (true)
{
lock (Tests.testLock)
{
DisplayAllResultInUIGrid(TestHolder.ExecutedTests);
}
Thread.Sleep(200);
}
}
}
class Test
{
public string Result { get; set; }
}
class Tests
{
public static readonly object testLock = new object();
public List<Test> ExecutedTests;
public Tests()
{
ExecutedTests = new List<Test>();
}
}
class UIManager
{
public static void DisplayAllResultInUIGrid(List<Test> list)
{
//Code to update UI.
}
}
Considering that the scope is to not update the UI while the other thread is adding tests to the list, it is safe to use:
lock (Tests.testLock)
or should I use:
lock (TestHolder.testLock)
(changing the static property of testLock)?
Do you think this is a good way to write this kind of program or can you suggest a better pattern?
Thank you for your help!
Public (not talking about public static) lock objects tend to be dangerous. Please see here
The reason it's bad practice to lock on a public object is that you can never be sure who ELSE is locking on that object.
Furthermore just having a List<T> and adding objects from an outer scope could be a smell, too.
In my opinion it'd be a better idea to have a method AddTest in Tests
class Tests
{
private static readonly object testLock = new object();
private List<Test> executedTests;
public Tests()
{
ExecutedTests = new List<Test>();
}
public void AddTest(Test t)
{
lock(testLock)
{
executedTests.Add(t);
}
}
public IEnumerable<Test> GetTests()
{
lock(testLock)
{
return executedTests.ToArray();
}
}
[...]
}
Clients of your tests class do not have to worry about using the lock object correctly. Precisely, they don't have to worry about any of the internals of your class.
You could, anyway, rename your class to ConcurrentTestsCollectionor the like, that users of the class know, that it's thread safe to some extent.
While you can use Tasks and the async/await keywords to do this less verbosely, I don't think it will fully solve your question.
I will assume that ExecutedTests is a List(or like) that you want to be thread safe, which is why you are creating a lock while accessing it.
I would make the list, itself, thread safe, rather than the operations against it. This will remove the need for a lock or a lock object.
You could implement this yourself or use something in the System.Collections.Concurrent namespace.
P.S.
If the threads are meant to be closed(aborted) when the process is exited you should set the Thread's IsBackground property to true.
Using Task Parallel Library in .net 4.0, I want to know what is the best solution to this situation :
My code is starting a task that do a lot of long running steps (steps need to be done one after other).
I have an object Result that aggregate the result of each steps.
The result object is modified in the task ( so in the thread related to this task ).
I also have an web service where we can fetch the current Result object to see the progress of the task.
So the Result object is a share object between the task and the main thread of my code. What is the best approach to implement this to be sure I don't have threading issues and things like that ?
Here a sample of what i'm talking about. Just note that _doWork would not be a static like in the code, it will be a member in another class higher in the hierarchy.
using System.Threading.Tasks;
namespace ConsoleApplication
{
public class Step1Result
{
}
public class Step2Result
{
}
public class Result
{
public Step1Result Step1Result;
public Step2Result Step2Result;
}
class DoWork
{
public Result Result;
public DoWork()
{
Result = new Result();
}
public void Process()
{
// Execute Step 1
Result.Step1Result = Step1();
Result.Step2Result = Step2();
// Other Steps ( long - running )
}
public Step1Result Step1()
{
// Long running step that can takes minutes
return new Step1Result();
}
public Step2Result Step2()
{
// Long running step that can takes minutes
return new Step2Result();
}
}
class Program
{
private static DoWork _doWork;
static void Main(string[] args)
{
_doWork = new DoWork();
var task = Task.Factory.StartNew(() => _doWork.Process());
task.Wait();
}
// This method will be called from a web service at anytime.
static Result CalledFromWebService()
{
return _doWork.Result;
}
}
}
The trouble here is accessing _doWork.Result from both the Task and the Main thread. True ? What could be done to overcome this ?
I would change DoWork.Result property to GetCurrentResult() method and return each time a new copy of current operation result (you can copy object using MemberwiseClone). I dont see any need to share the same object.
Additionalty, I would use ReadWriteLockSlim. So DoWork class will look like this
class DoWork
{
private readonly Result _result;
private readonly ReadWriteLockSlim _lock = new ReadWriteLockSlim();
public DoWork()
{
_result = new Result();
}
public void Process()
{
// Execute Step 1
Step1Result st1result = Step1();
try
{
_lock.EnterWriteLock();
_result.Step1Result = st1result;
}
finally
{
_lock.ExitWriteLock();
}
Step2Result st2result = Step2();
try
{
_lock.EnterWriteLock();
_result.Step2Result = st2result;
}
finally
{
_lock.ExitWriteLock();
}
// Other Steps ( long - running )
}
public Step1Result Step1()
{
// Long running step that can takes minutes
return new Step1Result();
}
public Step2Result Step2()
{
// Long running step that can takes minutes
return new Step2Result();
}
public Result GetCurrentResult()
{
try
{
_lock.EnterReadLock();
return (Result)_result.MemberwiseCopy();
}
finally
{
_lock.ExitReadLock();
}
}
}
If I understand the problem correctly you don't have thread safety issues accessing the Result object.
As you say the steps have to be finished one after each other so you won't be able to run them concurrently.
So inside Process() you can start Step1 in a task, then .Continue with Step2 in another task etc
Therefore you have a single writer thread and no concurrency issues. In this scenario it doesn't matter if you have another thread accessing the
result if that's a read-only fetching thread
You would only need a concurrent collection like ConcurrentDictionary to store the result if you were accessing a collection from different threads.
You would only need a ReadWriteLockSlim if the steps are not run one after each other and you had more than one writer
Your only concern here is dirty reads of the Result object returned from CalledFromWebService. You could add boolean properties to your Result object and remove the need for locks like so:
public class Result
{
public volatile bool IsStep1Valid;
public Step1Result Step1Result;
public volatile bool IsStep2Valid;
public Step2Result Step2Result;
}
Assignment to boolean values are atomic, so you don't have to worry about dirty reads and writes. You could then use those boolean values in your Process method like so:
public void Process()
{
// Execute Step 1
Result.Step1Result = Step1();
Result.IsStep1Valid = true;
Result.Step2Result = Step2();
Result.IsStep2Valid = true;
// Other Steps ( long - running )
}
Notice that the assignment to IsStep1Valid is after the assignment to Step1Result this ensures that Step1Result has a value assigned to it from the Task before IsStep1Valid is set to true.
Now when you access the result in your main thread by calling CalledFromWebService you can simply do the following:
void MyCode() {
var result = Program.CalledFromWebService();
if (result.IsStep1Valid) {
// do stuff with result.Step1Result
} else {
// if need be notify the user that step 1 is not complete yet
}
if (result.IsStep2Valid) {
// do stuff with result.Step2Result
}
// etc.
}
Checking the value of IsStep1Valid before you try to access the Step1Result property ensures that you are not getting a dirty read of the Step1Result property.
Update: A separate web service will not have access to the result object in the windows service because they run in separate app domains. You will need to expose a web service from inside your windows service, and have the main thread of the windows service load the web service and call your background task. You don't have to publicly expose this web service. You can still host a web service in IIS or where ever you originally intended. It would simply call the web service hosted by the windows service.
I am working on a web application, where several users can update the same record. So to avoid a problem if users are updating the same record at the same time, I am saving their changes in a queue. When each save occurs, I want to call a method that processes the queue on another thread, but I need to make sure that the method cannot run in another thread if it is called again. I’ve read several posts on the subject, but not sure what is best for my situation. Below is the code I have now. Is this the correct way to handle it?
public static class Queue {
static volatile bool isProcessing;
static volatile object locker = new Object();
public static void Process() {
lock (locker) {
if (!isProcessing) {
isProcessing = true;
//Process Queue...
isProcessing = false;
}
}
}
}
New answer
If you are persisting these records to a database (or data files, or similar persistence system) you should let that underlying system handle the synchronization. As JohnSaunders pointed out Databases already handle simultaneous updates.
Given you want to persist the records… the problem presented by John is that you are only synchronizing the access to the data in a single instance of the web application. Still, there could be multiple instances running at the same time (for example in a server farm, which may be a good idea if you have high traffic). In this scenario using a queue to prevent simultaneous writes is not good enough because there is still a race condition among the multiple instances of the web page.
In that case, when you get updates for the same record from different instances, then the underlying system will have to handle the collision anyway, yet it will not be able to do it reliably because the order of the updates has been lost.
In addition to that problem, if you are using this data structure as a cache, then it will provide incorrect data because it is not aware of the updates that happen in another instance.
With that said, for the scenarios where it may be worth to use a Thread-Safe Queue. For those cases you could use ConcurrentQueue (as I mention at the end of my original answer).
I'll keep my original answer, because I see value in helping understand the threading synchronization mechanism available in .NET (of which I present a few).
Original answer
Using lock is enough to prevent the access of multiple threads to a code segment at the same time (this is mutual exclusion).
Here I have commented out what you don't need:
public static class Queue {
// static volatile bool isProcessing;
static /*volatile*/ object locker = new Object();
public static void Process() {
lock (locker) {
// if (!isProcessing) {
// isProcessing = true;
//Process Queue...
// isProcessing = false;
// }
}
}
}
The lock does NOT need volatile to work. However you might still need the variable to be volatile due to other code not included here.
With that said, all the threads that try to enter in the lock will be waiting in a queue. Which as I understand is not what you want. Instead you want all the other threads to skip the block and leave only one do the work. This can be done with Monitor.TryEnter:
public static class Queue
{
static object locker = new Object();
public static void Process()
{
bool lockWasTaken = false;
try
{
if (Monitor.TryEnter(locker))
{
lockWasTaken = true;
//Process Queue…
}
}
finally
{
if (lockWasTaken)
{
Monitor.Exit(locker);
}
}
}
}
Another good alternative is to use Interlocked:
public static class Queue
{
static int status = 0;
public static void Process()
{
bool lockWasTaken = false;
try
{
lockWasTaken = Interlocked.CompareExchange(ref status, 1, 0) == 0;
if (lockWasTaken)
{
//Process Queue…
}
}
finally
{
if (lockWasTaken)
{
Volatile.Write(ref status, 0);
// For .NET Framework under .NET 4.5 use Thread.VolatileWrite instead.
}
}
}
}
Anyway, you don't have the need to implement your own thread-safe queue. You could use ConcurrentQueue.
A lock is good but it won't work for async await. You will get the following error if you try to await a method call in a lock:
CS1996 Cannot await in the body of a lock statement
In this case you should use a SemaphoreSlim
Example:
public class TestModel : PageModel
{
private readonly ILogger<TestModel> _logger;
private static readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
public TestModel(ILogger<TestModel> logger)
{
_logger = logger;
}
public async Task OnGet()
{
await _semaphoreSlim.WaitAsync();
try
{
await Stuff();
}
finally
{
_semaphoreSlim.Release();
}
}
}
It is important to not new SemaphoreSlim in the constructor or anywhere else because then it won't work.
https://stackoverflow.com/a/18257065/3850405
https://learn.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=net-5.0
I have simple method in my C# app, it picks file from FTP server and parses it and stores the data in DB. I want it to be asynchronous, so that user perform other operations on App, once parsing is done he has to get message stating "Parsing is done".
I know it can achieved through asynchronous method call but I dont know how to do that can anybody help me please??
You need to use delegates and the BeginInvoke method that they contain to run another method asynchronously. A the end of the method being run by the delegate, you can notify the user. For example:
class MyClass
{
private delegate void SomeFunctionDelegate(int param1, bool param2);
private SomeFunctionDelegate sfd;
public MyClass()
{
sfd = new SomeFunctionDelegate(this.SomeFunction);
}
private void SomeFunction(int param1, bool param2)
{
// Do stuff
// Notify user
}
public void GetData()
{
// Do stuff
sfd.BeginInvoke(34, true, null, null);
}
}
Read up at http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx
try this method
public static void RunAsynchronously(Action method, Action callback) {
ThreadPool.QueueUserWorkItem(_ =>
{
try {
method();
}
catch (ThreadAbortException) { /* dont report on this */ }
catch (Exception ex) {
}
// note: this will not be called if the thread is aborted
if (callback!= null) callback();
});
}
Usage:
RunAsynchronously( () => { picks file from FTP server and parses it},
() => { Console.WriteLine("Parsing is done"); } );
Any time you're doing something asynchronous, you're using a separate thread, either a new thread, or one taken from the thread pool. This means that anything you do asynchronously has to be very careful about interactions with other threads.
One way to do that is to place the code for the async thread (call it thread "A") along with all of its data into another class (call it class "A"). Make sure that thread "A" only accesses data in class "A". If thread "A" only touches class "A", and no other thread touches class "A"'s data, then there's one less problem:
public class MainClass
{
private sealed class AsyncClass
{
private int _counter;
private readonly int _maxCount;
public AsyncClass(int maxCount) { _maxCount = maxCount; }
public void Run()
{
while (_counter++ < _maxCount) { Thread.Sleep(1); }
CompletionTime = DateTime.Now;
}
public DateTime CompletionTime { get; private set; }
}
private AsyncClass _asyncInstance;
public void StartAsync()
{
var asyncDoneTime = DateTime.MinValue;
_asyncInstance = new AsyncClass(10);
Action asyncAction = _asyncInstance.Run;
asyncAction.BeginInvoke(
ar =>
{
asyncAction.EndInvoke(ar);
asyncDoneTime = _asyncInstance.CompletionTime;
}, null);
Console.WriteLine("Async task ended at {0}", asyncDoneTime);
}
}
Notice that the only part of AsyncClass that's touched from the outside is its public interface, and the only part of that which is data is CompletionTime. Note that this is only touched after the asynchronous task is complete. This means that nothing else can interfere with the tasks inner workings, and it can't interfere with anything else.
Here are two links about threading in C#
Threading in C#
Multi-threading in .NET: Introduction and suggestions
I'd start to read about the BackgroundWorker class
In Asp.Net I use a lot of static methods for jobs to be done. If its simply a job where I need no response or status, I do something simple like below. As you can see I can choose to call either ResizeImages or ResizeImagesAsync depending if I want to wait for it to finish or not
Code explanation: I use http://imageresizing.net/ to resize/crop images and the method SaveBlobPng is to store the images to Azure (cloud) but since that is irrelevant for this demo I didn't include that code. Its a good example of time consuming tasks though
private delegate void ResizeImagesDelegate(string tempuri, Dictionary<string, string> versions);
private static void ResizeImagesAsync(string tempuri, Dictionary<string, string> versions)
{
ResizeImagesDelegate worker = new ResizeImagesDelegate(ResizeImages);
worker.BeginInvoke(tempuri, versions, deletetemp, null, null);
}
private static void ResizeImages(string tempuri, Dictionary<string, string> versions)
{
//the job, whatever it might be
foreach (var item in versions)
{
var image = ImageBuilder.Current.Build(tempuri, new ResizeSettings(item.Value));
SaveBlobPng(image, item.Key);
image.Dispose();
}
}
Or going for threading so you dont have to bother with Delegates
private static void ResizeImagesAsync(string tempuri, Dictionary<string, string> versions)
{
Thread t = new Thread (() => ResizeImages(tempuri, versions, null, null));
t.Start();
}
ThreadPool.QueueUserWorkItem is the quickest way to get a process running on a different thread.
Be aware that UI objects have "thread affinity" and cannot be accessed from any thread other than the one that created them.
So, in addition to checking out the ThreadPool (or using the asynchronous programming model via delegates), you need to check out Dispatchers (wpf) or InvokeRequired (winforms).
In the end you will have to use some sort of threading. The way it basically works is that you start a function with a new thread and it will run until the end of the function.
If you are using Windows Forms then a nice wrapper that they have for this is call the Background Worker. It allows you to work in the background with out locking up the UI form and even provides a way to communicate with the forms and provide progress update events.
Background Worker
.NET got new keyword async for asonchrynous functions. You can start digging at learn.microsoft.com (async). The shortest general howto make function asonchrynous is to change function F:
Object F(Object args)
{
...
return RESULT;
}
to something like this:
async Task<Object> FAsync(Object args)
{
...
await RESULT_FROM_PROMISE;
...
return RESULT;
}
The most important thing in above code is that when your code approach await keyword it return control to function that called FAsync and make other computation until promissed value has been returned and procede with rest of code in function FAsync.
I'm reading a c# book that describes the SyncRoot pattern. It shows
void doThis()
{
lock(this){ ... }
}
void doThat()
{
lock(this){ ... }
}
and compares to the SyncRoot pattern:
object syncRoot = new object();
void doThis()
{
lock(syncRoot ){ ... }
}
void doThat()
{
lock(syncRoot){ ... }
}
However, I don't really understand the difference here; it seems that in both cases both methods can only be accessed by one thread at a time.
The book describes ... because the object of the instance can also be used for synchronized access from the outside and you can't control this form the class itself, you can use the SyncRoot pattern Eh? 'object of the instance'?
Can anyone tell me the difference between the two approaches above?
If you have an internal data structure that you want to prevent simultaneous access to by multiple threads, you should always make sure the object you're locking on is not public.
The reasoning behind this is that a public object can be locked by anyone, and thus you can create deadlocks because you're not in total control of the locking pattern.
This means that locking on this is not an option, since anyone can lock on that object. Likewise, you should not lock on something you expose to the outside world.
Which means that the best solution is to use an internal object, and thus the tip is to just use Object.
Locking data structures is something you really need to have full control over, otherwise you risk setting up a scenario for deadlocking, which can be very problematic to handle.
The actual purpose of this pattern is implementing correct synchronization with wrappers hierarchy.
For example, if class WrapperA wraps an instance of ClassThanNeedsToBeSynced, and class WrapperB wraps the same instance of ClassThanNeedsToBeSynced, you can't lock on WrapperA or WrapperB, since if you lock on WrapperA, lock on WrappedB won't wait.
For this reason you must lock on wrapperAInst.SyncRoot and wrapperBInst.SyncRoot, which delegate lock to ClassThanNeedsToBeSynced's one.
Example:
public interface ISynchronized
{
object SyncRoot { get; }
}
public class SynchronizationCriticalClass : ISynchronized
{
public object SyncRoot
{
// you can return this, because this class wraps nothing.
get { return this; }
}
}
public class WrapperA : ISynchronized
{
ISynchronized subClass;
public WrapperA(ISynchronized subClass)
{
this.subClass = subClass;
}
public object SyncRoot
{
// you should return SyncRoot of underlying class.
get { return subClass.SyncRoot; }
}
}
public class WrapperB : ISynchronized
{
ISynchronized subClass;
public WrapperB(ISynchronized subClass)
{
this.subClass = subClass;
}
public object SyncRoot
{
// you should return SyncRoot of underlying class.
get { return subClass.SyncRoot; }
}
}
// Run
class MainClass
{
delegate void DoSomethingAsyncDelegate(ISynchronized obj);
public static void Main(string[] args)
{
SynchronizationCriticalClass rootClass = new SynchronizationCriticalClass();
WrapperA wrapperA = new WrapperA(rootClass);
WrapperB wrapperB = new WrapperB(rootClass);
// Do some async work with them to test synchronization.
//Works good.
DoSomethingAsyncDelegate work = new DoSomethingAsyncDelegate(DoSomethingAsyncCorrectly);
work.BeginInvoke(wrapperA, null, null);
work.BeginInvoke(wrapperB, null, null);
// Works wrong.
work = new DoSomethingAsyncDelegate(DoSomethingAsyncIncorrectly);
work.BeginInvoke(wrapperA, null, null);
work.BeginInvoke(wrapperB, null, null);
}
static void DoSomethingAsyncCorrectly(ISynchronized obj)
{
lock (obj.SyncRoot)
{
// Do something with obj
}
}
// This works wrong! obj is locked but not the underlaying object!
static void DoSomethingAsyncIncorrectly(ISynchronized obj)
{
lock (obj)
{
// Do something with obj
}
}
}
Here is an example :
class ILockMySelf
{
public void doThat()
{
lock (this)
{
// Don't actually need anything here.
// In this example this will never be reached.
}
}
}
class WeveGotAProblem
{
ILockMySelf anObjectIShouldntUseToLock = new ILockMySelf();
public void doThis()
{
lock (anObjectIShouldntUseToLock)
{
// doThat will wait for the lock to be released to finish the thread
var thread = new Thread(x => anObjectIShouldntUseToLock.doThat());
thread.Start();
// doThis will wait for the thread to finish to release the lock
thread.Join();
}
}
}
You see that the second class can use an instance of the first one in a lock statement. This leads to a deadlock in the example.
The correct SyncRoot implementation is:
object syncRoot = new object();
void doThis()
{
lock(syncRoot ){ ... }
}
void doThat()
{
lock(syncRoot ){ ... }
}
as syncRoot is a private field, you don't have to worry about external use of this object.
Here's one other interesting thing related to this topic:
Questionable value of SyncRoot on Collections (by Brad Adams):
You’ll notice a SyncRoot property on many of the Collections in System.Collections. In retrospeced (sic), I think this property was a mistake. Krzysztof Cwalina, a Program Manger on my team, just sent me some thoughts on why that is – I agree with him:
We found the SyncRoot-based synchronization APIs to be insufficiently flexible for most scenarios. The APIs allow for thread safe access to a single member of a collection. The problem is that there are numerous scenarios where you need to lock on multiple operations (for example remove one item and add another). In other words, it’s usually the code that uses a collection that wants to choose (and can actually implement) the right synchronization policy, not the collection itself. We found that SyncRoot is actually used very rarely and in cases where it is used, it actually does not add much value. In cases where it’s not used, it is just an annoyance to implementers of ICollection.
Rest assured we will not make the same mistake as we build the generic versions of these collections.
See this Jeff Richter's article. More specifically, this example which demonstrates that locking on "this" can cause a deadlock:
using System;
using System.Threading;
class App {
static void Main() {
// Construct an instance of the App object
App a = new App();
// This malicious code enters a lock on
// the object but never exits the lock
Monitor.Enter(a);
// For demonstration purposes, let's release the
// root to this object and force a garbage collection
a = null;
GC.Collect();
// For demonstration purposes, wait until all Finalize
// methods have completed their execution - deadlock!
GC.WaitForPendingFinalizers();
// We never get to the line of code below!
Console.WriteLine("Leaving Main");
}
// This is the App type's Finalize method
~App() {
// For demonstration purposes, have the CLR's
// Finalizer thread attempt to lock the object.
// NOTE: Since the Main thread owns the lock,
// the Finalizer thread is deadlocked!
lock (this) {
// Pretend to do something in here...
}
}
}
Another concrete example:
class Program
{
public class Test
{
public string DoThis()
{
lock (this)
{
return "got it!";
}
}
}
public delegate string Something();
static void Main(string[] args)
{
var test = new Test();
Something call = test.DoThis;
//Holding lock from _outside_ the class
IAsyncResult async;
lock (test)
{
//Calling method on another thread.
async = call.BeginInvoke(null, null);
}
async.AsyncWaitHandle.WaitOne();
string result = call.EndInvoke(async);
lock (test)
{
async = call.BeginInvoke(null, null);
async.AsyncWaitHandle.WaitOne();
}
result = call.EndInvoke(async);
}
}
In this example, the first call will succeed, but if you trace in the debugger the call to DoSomething will block until the lock is release. The second call will deadlock, since the Main thread is holding the monitor lock on test.
The issue is that Main can lock the object instance, which means that it can keep the instance from doing anything that the object thinks should be synchronized. The point being that the object itself knows what requires locking, and outside interference is just asking for trouble. That's why the pattern of having a private member variable that you can use exclusively for synchronization without having to worry about outside interference.
The same goes for the equivalent static pattern:
class Program
{
public static class Test
{
public static string DoThis()
{
lock (typeof(Test))
{
return "got it!";
}
}
}
public delegate string Something();
static void Main(string[] args)
{
Something call =Test.DoThis;
//Holding lock from _outside_ the class
IAsyncResult async;
lock (typeof(Test))
{
//Calling method on another thread.
async = call.BeginInvoke(null, null);
}
async.AsyncWaitHandle.WaitOne();
string result = call.EndInvoke(async);
lock (typeof(Test))
{
async = call.BeginInvoke(null, null);
async.AsyncWaitHandle.WaitOne();
}
result = call.EndInvoke(async);
}
}
Use a private static object to synchronize on, not the Type.