2016-04-21 13 views
-1

Ich bin mir nicht sicher über den Prozess, den CLR beim Ausführen eines Programms ausführt. Ich weiß nicht genau, wann ich lock() oder eine andere Art von Thread-sicheren Objekten verwenden soll.Grundlegendes zum Multithreading- und Ausführungsprozess

Bitte helfen Sie mir zu verstehen, die folgende:

diesen Code zu haben:

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 
    } 

} 

Bitte korrigieren Sie mich, wenn ich falsch liege, aber das ist mein Verständnis von Beispiel 1 Single-Threaded-App (nehme an, es ist eine mvc-anwendung und ich benutze DI und bereits registriert "Service" in den container.

Ich rufe Service.Work() von irgendwo in meiner anwendung new Calc() erstellt (CLR reserviert dieses objekt im speicher) und Calc.DoStuff() berechnet die Berechnung für Person obj ect. Da vor dem Aufruf neuer Calc() erstellt wird und von zwei Browsern aufgerufen wird, befinden sie sich in separaten Ausführungspfaden. Ist das richtig?

// 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); 
    } 
} 

Nun, was im gleichen Szenario passiert, aber diesmal zum Zeitpunkt Dienst der Zuweisung im Speicher Calc wird in dem Dienst des Konstruktor instanziiert. Würde dies Probleme bei gleichzeitigem Aufruf von Work() verursachen (da es nur EINE Instanz von Calc gibt?

  • Was passiert dann? Würde der String-Name mit der "neuesten" Zeichenfolge gefüllt?).
  • Wäre hier eine Sperre erforderlich, so dass zuerst die erste Anrufanforderung und dann die zweite beendet werden muss?
  • Was geschieht, wenn zwei Browser Work (Person) aufrufen und zwei Instanzen von Person an diese Methode senden. Angenommen, Person Objekte gehen "ins" Calc-Klasse und dann wird eine externe API aufgerufen - und bleibt für ein bisschen stehen. Dann wird die zweite Anfrage zu Calc (Person) aufgerufen, würde dieses Person-Objekt unabhängig aktualisiert werden (obwohl es nur eine Instanz von Calc() gibt?). Oder würde die erste Anfrage (diejenige, die zum Stillstand gekommen ist) vom zweiten abgebrochen und vergessen?
+0

"So, wenn zwei Browser Calc.DoStuff() ausführen ..." - Sie erwähnten Browser. Ist das eine ASP.NET-Anwendung? – mbeckish

+0

ja und nein - Weil es Browser sein könnte aber es könnte sein, dass zwei verschiedene Komponenten der Anwendung gleichzeitig Service.Work() aufrufen. Macht das einen Unterschied? Wenn es Asp.net ist oder nicht? – BobSwanson

Antwort

0

Hier ist, wo Sie Ihre Intuition falsch gelaufen ist:

Nun, was im gleichen Szenario passiert, aber diesmal zum Zeitpunkt of Service Zuweisung im Speicher Calc im Konstruktor Dienst instanziiert wird. Wäre das zu Problemen führt, mit den gleichzeitigen Anrufen Arbeit() (da es nur eine Instanz von Calc ist? Objekt.

Jeder Aufruf der Service-Funktion verfügt über einen eigenen Thread-Stack und damit getrennte Kopien aller lokalen Variablen.

Für alle Absichten und Zwecke, Bild nur die beiden Browser-Anfragen als zwei völlig getrennte Programme.

+0

Ich dachte, es gibt nur einen Thread-Stack ?. Gilt das auch für die Konsolen-App? Angenommen, Sie rufen den Dienst aus zwei "Bereichen" der Konsolenanwendung gleichzeitig auf. – BobSwanson

+0

Nein. Diese zwei Browseranforderungen werden gleichzeitig von separaten Threads im Webserver verarbeitet. – mbeckish

+0

In einer Konsolenanwendung würden Sie standardmäßig nur einen Thread haben, und so würde immer nur ein Aufruf an den Dienst erfolgen. Wenn Sie zwei Threads erstellen, um Service gleichzeitig aufzurufen, hat jeder einen eigenen Stack. – mbeckish

0

Allgemeinen in beiden Szenarien sollten Sie nicht die Instanz von Calc erwarten ist Single (Singleton), so dass Ihr Die DoStuff-Methode muss eine Art von Synchronisation haben, wie z. B. lock(p), i f Instanz der Klasse Person ist für alle Aufrufe gleich.