C# 线程上Lambda实例化的对象在比较时总是解析为null

C# 线程上Lambda实例化的对象在比较时总是解析为null,c#,multithreading,lambda,C#,Multithreading,Lambda,在下面的示例中,_实例总是解析为null。我应该如何安全地从线程中获取值 class GenericThreadManager<TMyClass> where TMyClass : new() { private TMyClass _instance; private object synLock = new object(); private Thread generalThread; public Gen

在下面的示例中,_实例总是解析为null。我应该如何安全地从线程中获取值

class GenericThreadManager<TMyClass> where TMyClass : new()
    {

        private TMyClass _instance;
        private object synLock = new object();
        private Thread generalThread;

        public GenericThreadManager()
        {
            //wrapped code
            lock (this.synLock)
            {
                generalThread = new Thread(_instance => this._instance = new TMyClass());
                generalThread.Start();      // instantiates the object

                while (this._instance == null)  // allways compares to null even after 
                            // thread completes
                {
                    Thread.Sleep(100);
                }
                Thread.Sleep(100);
            }
            //wrapped code
        }
我知道这个表达式创建了
TMyClass()
的一个新实例,并将对该对象的引用放置在
\u instance

然后我了解到线程不能同步,因此无法可靠地设置
\u实例
的值,除非将其设置为
volatile

设置为
volatile
时,我得到以下编译错误:

Error   CS0677  'GenericThreadManager<TMyClass>._instance': a volatile field cannot be of the type 'TMyClass'
错误CS0677“GenericThreadManager.\u实例”:易失性字段不能是“TMyClass”类型
如何解决上述错误或同步线程以将对对象的引用移动到
\u实例


@Panagiotis Kanavos您能解释一下为什么每个构造函数会看到不同的锁吗。
GenericThreadManager
正在
GenericThreadManager
构造函数中创建另一个对象
TMyClass
的私有实例。它锁定在
synLock
上,因此理论上,
GenericThreadManager
上的任何其他方法都应该在
锁(this.synLock)
上阻塞,如果我理解正确的话?

您没有使用线程本地存储,因此无法从线程中获取任何内容。您只是在修改另一个线程的变量。这需要从两个线程进行同步,但您没有使用任何有意义的锁定-synclock不提供任何保护-lock对象是一个实例字段,因此每个构造函数将看到一个不同的实例字段。这两个线程根本不同步。当前线程和新线程都试图同时访问和修改
\u实例
,您想做什么?为什么不使用内置机制,如Task.Run、TaskScheduler甚至直接使用线程池?另一个问题是,线程参数的名称与实例字段
\u instance
的名称相同。如果您不想传递任何参数,请使用
()=>
而不是另一个问题-您正在阻止构造函数,但lambda正在尝试访问捕获的对象。它还没有被创建。您从未检查新线程是否已完成,因此它可能引发了异常。我必须在一个调试器中测试它,看看它实际上做了什么。值只是被缓存,循环看不到更新。将
\u instance
字段标记为
volatile
以修复它(您还必须添加
where-TMyClass:class
通用约束)。也就是说,正如其他评论所指出的,可能有更好的方法来做你正在做的事情
Error   CS0677  'GenericThreadManager<TMyClass>._instance': a volatile field cannot be of the type 'TMyClass'