Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 了解多线程和执行过程_C#_.net_Multithreading - Fatal编程技术网

C# 了解多线程和执行过程

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 //

我不清楚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对象进行计算。因为在创建调用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
      对象是服务中的局部变量。