Question

Can someone please tell me what is wrong with the following code? Ideally it should start a thread first and then wait for the set event. Instead of that it does not start the thread and just get stuck on WaitOne().

I am curious to know what happened to the thread and why?

class Program
{   
    static void Main(string[] args)
    {
        Testing t = Testing.Instance;
        Console.Read();
    }
}


class Testing
{
    private static AutoResetEvent evt = new AutoResetEvent(false);
    public static Testing Instance = new Testing();

    private Testing()
    {
        Create();
        evt.WaitOne();
        Console.WriteLine("out");
    }

    private void Create()
    {
        Console.WriteLine("Starting thread");
        new Thread(Print).Start();
    }

    private void Print()
    {
        Console.WriteLine("started");
        evt.Set();
    }
}

EDIT: So far, the description provided by @BrokenGlass makes sense. but changing the code to the following code allows another thread can access the instance methods without constructor being completed.(Suggested by @NicoSchertler).

private static Testing _Instance;

public static Testing Instance
{
get
{
    if (_Instance == null)
        _Instance = new Testing();
    return _Instance;
}
}
Was it helpful?

Solution

I suspect the root cause of this behavior is that the spawned thread cannot access the Print method until the constructor has finished executing - but the constructor never finishes executing because it is waiting on the signal that is triggered only from the Print method.

Replacing the evt.WaitOne() with a long Thread.Sleep() call confirms the same behavior - the constructor must finish running before any instance method of the object may execute from another thread.

OTHER TIPS

The problem is that the second thread is created too early. I'm not sure why, but when started before the main program starts, it will not execute.

You should use the singleton pattern in its original version. This will work.

private static Testing _Instance;

public static Testing Instance
{
    get
    {
        if (_Instance == null)
            _Instance = new Testing();
        return _Instance;
    }
}

Additionally, you should not make the evt variable static. The instance variable should be the only static member of a singleton class in most cases.

My guess would be an issue with the relative timing of the static field initialization. Try initializing evt in the constructor of Testing instead:

private static AutoResetEvent evt;
public static Testing Instance = new Testing();

private Testing()
{
    evt = new AutoResetEvent(false);
    Create();
    evt.WaitOne();
    Console.WriteLine("out");
}

I should note this is really just a guess- I'd have thought this code would work fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top