c# - 为什么 SynchronizationContext.Current 为空?

标签 c# .net winforms multithreading

错误:未将对象引用设置为对象的实例。

下面的算法有效。 我试过了,然后我将 Winform 项目移到了另一个目录,SynchronizationContext.Currentnull。 为什么?

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/

相关文章:

c# - 在主线程中设置线程本地值并在另一个线程中获取

c# - 从 Windows 身份验证中获取 `ICredentials`

.net - LINQ to Entities 和 String.StartsWith 的问题

c# - Visual Studio 2022 for Mac 中未命中断点

c# - 如何将图像文件保存在我的项目文件夹中?

c# - 通用列表及对应方法

c# - 接口(interface)的 XML 序列化

c# - 如何在更新后不断刷新datagridview

C# 编写 Tic Tac Toe 中的领带

c# - 从具有两种类型的对象的列表中获取 ComboBox 选定值,并且组合框仅显示其中一种