C# 了解多线程和执行过程
我不清楚CLR在运行程序时执行的过程。我不太清楚何时使用lock()或其他类型的线程安全对象 请帮助我理解以下内容: 有此代码:C# 了解多线程和执行过程,c#,.net,multithreading,C#,.net,Multithreading,我不清楚CLR在运行程序时执行的过程。我不太清楚何时使用lock()或其他类型的线程安全对象 请帮助我理解以下内容: 有此代码: public class Person { string Name {get;set;} } public class Calc { public string DoStuff(Person p){ // perform some processing on person object //
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对象进行计算。因为在创建调用new 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在服务的构造函数中实例化。这会不会导致同时调用Work()的问题(因为只有一个Calc?对象实例)
- 然后会发生什么?字符串名称是否会填充“最新”字符串
- 这里是否需要锁,以便首先完成第一个呼叫请求,然后完成第二个呼叫请求
- 当两个浏览器调用Work(Person)并向该方法发送两个Person实例时会发生什么情况。假设Person对象进入Calc类,然后调用一个外部API,并暂停一段时间。然后调用Calc(Person)的第二个请求,该Person对象是否会独立更新(即使只有一个Calc()实例?)。或者第一个请求(暂停的请求)会被第二个请求取消并被忘记吗
- 这里是你直觉出错的地方:
现在,在同一个场景中会发生什么,但是这次呢
在服务的
构造函数。这会导致同时调用的问题吗
Work()(因为Calc?对象只有一个实例
对服务函数的每个调用都有自己的线程堆栈,因此所有局部变量都有单独的副本
出于所有意图和目的,只需将两个浏览器请求想象成两个完全独立的程序。一般来说,在这两种情况下,您不应该期望Calc的实例是单实例(singleton),因此您的DoStuff方法需要某种同步,如
lock(p)
,例如,如果类Person的实例对于所有调用都相同。“那么如果两个浏览器执行Calc.DoStuff()…”-您提到的浏览器。这是ASP.NET应用程序吗?是和否-因为它可能是浏览器,但可能是应用程序调用服务的两个不同组件。Work()同时。这有区别吗?如果它是Asp.net还是非Asp.net?我以为只有一个线程堆栈?这同样适用于控制台应用程序。假设您从两个“区域”调用服务不。这两个浏览器请求由web服务器中的不同线程同时处理。在控制台应用中,默认情况下,您只有一个线程,因此一次只能调用一个服务。如果您创建了两个线程,同时调用服务,则每个线程都有自己的堆栈。因此CLR做自己的线程安全检查?你的意思是:假设我有一堆其他的“服务”做一些工作,偶尔他们用不同的Person实例调用Service.work(Person)。不会有一个实例会被破坏。对吗?不,这不是线程安全问题。如果你的服务()方法访问共享资源(服务器上的文件、全局变量等),然后您需要手动添加锁定代码以防止并发问题。但是您的示例没有显式显示任何共享资源。Calc
对象是服务中的局部变量。