我不清楚CLR在运行程序时执行的过程。我不太清楚何时使用lock()或其他类型的线程安全对象。
请帮助我理解以下内容:
拥有此代码:
public class Person {
string Name {get;set;}
}
public class Calc {
public string DoStuff(Person p){
// perform some processing on person object
// maybe call external API and update person object
}
}
如果我错了,请纠正我,但这是我对示例1的理解。在单线程应用程序中(假设它是mvc应用程序并且我使用DI并且已经注册了"服务"在容器中。
我从应用程序的某个地方调用Service.Work()。创建了新的Calc()(CLR在内存中分配此对象),Calc.DoStuff()在Person对象上进行计算。从调用之前开始,新的Calc()被创建并从两个浏览器调用,它们位于不同的执行路径中。这是对的吗?
// Example 1
public class Service {
public void Work(person) {
var calc = new Calc();
string test = calc.DoStuff(person);
}
}
// Example 2
public class Service {
public Service() {
var calc = new Calc(); // this is different
}
public void Work(person) {
string test = calc.DoStuff(person);
}
}
现在在同一场景中会发生什么,但是这次在内存中分配服务时,Calc会在Service的构造函数中实例化。这会导致同时调用Work()的问题(因为只有一个Calc?object实例。
答案 0 :(得分:0)
这是你的直觉出错的地方:
现在,在同一场景中会发生什么,但这次是在当时 在内存中分配服务Calc在服务中实例化 构造函数。这会导致同时调用问题吗? Work()(因为只有一个Calc?对象的实例。
对Service函数的每次调用都有自己的线程堆栈,因此是所有局部变量的单独副本。
出于所有意图和目的,只需将两个浏览器请求描述为两个完全独立的程序。
答案 1 :(得分:0)
一般来说,在这两种情况下,您都不应该期望Calc的实例是单个(单例),因此您的DoStuff方法需要具有某种类型的同步,例如lock(p)
,如果类的实例是Person所有电话都是一样的。