This is closely related to Is it safe to signal and immediately close a ManualResetEvent? and might provide one solution to that problem.
Say I have a bunch of threads that potentially want to do the same work, but only one should be allowed to do it, and the others should wait until the worker is done and use its result.
So basically do I want work to be done only once.
Update: Let me add that this is not an initialization problem that could be addressed using .net 4's Lazy<T>. By once I mean once per task, and those tasks are determined at runtime. This might not be clear from the simplified example below.
Modifying the simple example from Hans Passant's answer to aforementioned question a bit, I guess the following would be safe. (It's slightly different from the use case just described, but in terms of threads and their relations, it is equivalent)
static void Main(string[] args)
{
ManualResetEvent flag = new ManualResetEvent(false);
object workResult = null;
for (int ix = 0; ix < 10; ++ix)
{
ThreadPool.QueueUserWorkItem(s =>
{
try
{
flag.WaitOne();
Console.WriteLine("Work Item Executed: {0}", workResult);
}
catch (ObjectDisposedException)
{
Console.WriteLine("Finished before WaitOne: {0}", workResult);
}
});
}
Thread.Sleep(1000);
workResult = "asdf";
flag.Set();
flag.Close();
Console.WriteLine("Finished");
}
I guess the core of my question is:
Is a call to WaitOne, aborted due to a ObjectDisposedException, equivalent to a successful call to WaitOne, in terms of memory barriers?
That should ensure safe access to the variable workResult by those other threads.
My guess: It would have to be safe, otherwise how could WaitOne safely figure out that the ManualResetEvent object had been closed in the first place?