Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is SynchronizationContext.Current null?

Error: Object reference not set to an instance of an object.

The algorithm below works. I tried it, then I removed the Winform project to another directory and SynchronizationContext.Current is null. Why?

SynchronizationContext uiCtx = SynchronizationContext.Current;  

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    int[] makeSelfMoves = new int[4];

    lock (replay)
    {
        // count should be more than 2
        foreach (KeyValuePair<int, int[]> item in replay)
        {              
            makeSelfMoves = replay[item.Key];
            codeFile.ExecuteAll(makeSelfMoves[0],
              makeSelfMoves[1], makeSelfMoves[2], makeSelfMoves[3]);

            // i get the error here. uictx is null
            uiCtx.Post(o =>
            {
                PrintPieces(codeFile.PieceState());
            }, null);                               

            System.Threading.Thread.Sleep(1000);
        }
    }
}
like image 999
Dmitry Makovetskiyd Avatar asked Aug 16 '11 08:08

Dmitry Makovetskiyd


1 Answers

Your code critically depends on exactly when and where the constructor of your class runs. SynchronizationContext.Current will be null when:

  • your class object is created too soon, before your code creates an instance of the Form class or calls Application.Run() in Main(). That's when the Current member is set to an instance of WindowsFormsSynchronizationContext, the class that knows how to marshal calls with the message loop. Fix this by moving your object instancing code to the main form constructor.

  • your class object is created on any thread other than the main UI thread. Only the UI thread in a Winforms application can marshal calls. Diagnose this by adding a constructor to your class with this statement:

      Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
    

Also add this line to the Main() method in Program.cs. It won't work if the displayed value in the Output window is different. Fix this by moving your object instancing code to, again, the main form constructor so you can be sure it runs on the UI thread.

like image 116
Hans Passant Avatar answered Nov 10 '22 00:11

Hans Passant