错误:未将对象引用设置为对象的实例。
下面的算法有效。
我试过了,然后我将 Winform
项目移到了另一个目录,SynchronizationContext.Current
为 null
。
为什么?
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);
}
}
}
最佳答案
您的代码严重依赖于类的构造函数运行的确切时间和位置。 SynchronizationContext.Current 在以下情况下将为空:
您的类对象创建得太早,在您的代码创建 Form 类的实例或在 Main() 中调用 Application.Run() 之前。那时 Current 成员被设置为 WindowsFormsSynchronizationContext 的实例,该类知道如何使用消息循环编码调用。通过将对象实例化代码移动到主窗体构造函数来解决此问题。
您的类对象是在主 UI 线程以外的任何线程上创建的。只有 Winforms 应用程序中的 UI 线程可以编码调用。通过使用以下语句向您的类添加构造函数来诊断此问题:
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
还将此行添加到 Program.cs 中的 Main() 方法。如果输出窗口中显示的值不同,它将不起作用。通过再次将对象实例化代码移动到主窗体构造函数来解决此问题,这样您就可以确保它在 UI 线程上运行。
关于c# - 为什么 SynchronizationContext.Current 为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7075491/