为什么SynchronizationContext.Current空? [英] Why is SynchronizationContext.Current null?

查看:398
本文介绍了为什么SynchronizationContext.Current空?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

错误:对象引用不设置到对象的实例

下面工作的算法。 我试了一下,然后我删除了 WinForm的的项目到其他目录 SynchronizationContext.Current 。 为什么呢?

 的SynchronizationContext uiCtx = SynchronizationContext.Current;

私人无效backgroundWorker1_DoWork(对象发件人,DoWorkEventArgs E)
{
    INT [] makeSelfMoves =新INT [4];

    锁(重播)
    {
        //数应大于2
        的foreach(KeyValuePair< INT,INT []>在重播项)
        {
            makeSelfMoves =重播[item.Key]
            codeFile.ExecuteAll(makeSelfMoves [0]
              makeSelfMoves [1],makeSelfMoves [2],makeSelfMoves [3]);

            //我这里得到的错误。 uictx为null
            uiCtx.Post(O =>
            {
                PrintPieces(codeFile.PieceState());
            }, 空值);

            System.Threading.Thread.Sleep(1000);
        }
    }
}
 

解决方案

您code关键取决于究竟在何时何地你的类运行的构造函数。 SynchronizationContext.Current将空时:

  • 你的类对象被创建太早,在你的code创建窗体类的实例或调用Application.Run()在main()。这时候,当前成员设置为WindowsFormsSynchronizationContext,知道如何元帅的消息循环调用这个类的一个实例。通过移动你的对象实例化code到主窗体构造函数解决这个问题。

  • 你的类对象上比主UI线程以外的任何线程创建。只有在一个WinForms应用程序的UI线程可以封送调用。通过增加一个构造函数类这种说法诊断这样的:

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

也加入这一行Program.cs中的Main()方法。如果在输出窗口中显示的值不同,它不会起作用。通过移动你的对象实例化code到,再次,主窗体构造函数,所以你可以确保它运行在UI线程上解决这个问题。

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);
        }
    }
}

解决方案

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.

这篇关于为什么SynchronizationContext.Current空?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆