Αυτό το άρθρο είναι ένα άρθρο καθρέφτη της αυτόματης μετάφρασης, κάντε κλικ εδώ για να μεταβείτε στο αρχικό άρθρο.

Άποψη: 3568|Απάντηση: 2

[Πηγή] ASP.NET τη διαφορά μεταξύ ThreadStatic, CallContext και HttpContext

[Αντιγραφή συνδέσμου]
Δημοσιεύτηκε στις 30/6/2023 8:34:10 μ.μ. | | |
Αρχικός:Η σύνδεση με υπερσύνδεσμο είναι ορατή.



Περίληψη:
Ακόμα κι αν νομίζετε ότι ξέρετε τι κάνετε, δεν είναι ασφαλές να αποθηκεύσετε τίποτα σε ένα κατάστημα μέλους ThreadStatic, CallContext ή Thread Local σε μια εφαρμογή ASP.Net, εάν η τιμή μπορεί να έχει οριστεί εκ των προτέρων. σε Page_Load (π.χ. στο IHttpModule ή στον κατασκευαστή σελίδων), αλλά κατά τη διάρκεια ή μετά την πρόσβαση.

[Ενημέρωση: Αύγουστος 2008 Δεδομένου ότι αρκετοί άνθρωποι συνεχίζουν να συνδέονται με αυτό το άρθρο, πιστεύω ότι είναι απαραίτητο να διευκρινιστεί ότι αυτή η συμπεριφορά ανταλλαγής νημάτων συμβαίνει σε ένα πολύ συγκεκριμένο σημείο του κύκλου ζωής της σελίδας και όχι όταν το θέλει.] Η διατύπωσή μου μετά την παράθεση του Jeff Newsom είναι ατυχής. Εκτός από αυτό, είμαι πολύ χαρούμενος (και κολακευμένος) που βλέπω αναφορές σε αυτό το άρθρο πολλές φορές σε συζητήσεις σχεδιασμού σχετικά με τον σωστό χειρισμό του HttpContext. Χαίρομαι που οι άνθρωποι το βρίσκουν χρήσιμο. ]

Υπάρχει μεγάλη σύγχυση σχετικά με τον τρόπο υλοποίησης singletons για συγκεκριμένους χρήστες σε ASP.Net - δηλαδή, τα καθολικά δεδομένα είναι καθολικά μόνο για έναν χρήστη ή αίτημα. Αυτή δεν είναι μια ασυνήθιστη απαίτηση: δημοσιεύστε δεδομένα συναλλαγών, πλαισίου ασφαλείας ή άλλα «παγκόσμια» δεδομένα σε ένα μέρος, αντί να τα προωθείτε σε κάθε κλήση μεθόδου, επειδή τα αργιλώδη δεδομένα επιτρέπουν μια σαφέστερη (και πιο ευανάγνωστη) υλοποίηση. Ωστόσο, αν δεν είστε προσεκτικοί, αυτό είναι ένα εξαιρετικό μέρος για να πυροβολήσετε τον εαυτό σας στο πόδι (ή στο κεφάλι). Νόμιζα ότι ήξερα τι συνέβαινε, αλλά δεν το ήξερα.

Η προτιμώμενη επιλογή θα είναι η απλή επιλογήΑποθηκευμένο στο HttpContext.Current.Items, απλό και ασφαλές, αλλά συσχετίζοντας το επίμαχο singleton με τη χρήση του στην ASP.Net αίτηση. Εάν το singleton αποτύχει στο αντικείμενο της επιχείρησής σας, τότε αυτό δεν είναι ιδανικό. Ακόμα και αν αναδιπλώσετε την πρόσβαση στην ιδιότητα σε μια δήλωση if


Summary:
Ακόμα κι αν νομίζετε ότι ξέρετε τι κάνετε, δεν είναι ασφαλές να αποθηκεύσετε τίποτα σε ένα μέλος ThreadStatic, CallContext ή Thread Local Storage σε μια εφαρμογή ASP.Net, εάν υπάρχει η πιθανότητα ότι η τιμή μπορεί να έχει ρυθμιστεί πριν από Page_Load (π.χ. στο IHttpModule ή στον κατασκευαστή σελίδων) αλλά να έχει πρόσβαση κατά τη διάρκεια ή μετά.

[Ενημέρωση: Αύγουστος 2008 Λαμβάνοντας υπόψη τον αρκετά μεγάλο αριθμό ατόμων που συνεχίζουν να συνδέονται με αυτήν την ανάρτηση, αισθάνομαι την ανάγκη να διευκρινίσω ότι αυτή η συμπεριφορά ανταλλαγής νημάτων συμβαίνει σε ένα πολύ συγκεκριμένο σημείο της σελίδας κύκλου ζωής και όχι όποτε του αρέσει. Η διατύπωσή μου μετά το απόσπασμα του Jef Newson ήταν ατυχής. Πέρα από αυτό, έχω μείνει εξαιρετικά ικανοποιημένος (και κολακευμένος) από τον αριθμό των φορών που έχω δει αυτήν την ανάρτηση να αναφέρεται σε συζητήσεις σχεδιασμού σχετικά με την κατάλληλη αντιμετώπιση του HttpContext. Χαίρομαι που οι άνθρωποι το βρήκαν χρήσιμο.]

Υπάρχει μεγάλη σύγχυση σχετικά με τη χρήση του τρόπου υλοποίησης singletons για συγκεκριμένους χρήστες σε ASP.Net - δηλαδή καθολικά δεδομένα που είναι καθολικά μόνο για έναν χρήστη ή αίτημα. Αυτή δεν είναι μια ασυνήθιστη απαίτηση: η δημοσίευση συναλλαγών, πλαισίου ασφαλείας ή άλλων «παγκόσμιων» δεδομένων σε ένα μέρος, αντί να τα προωθείτε μέσω κάθε κλήσης μεθόδου, καθώς τα δεδομένα tramp μπορούν να κάνουν ένα (και πιο ευανάγνωστη) εφαρμογή. Ωστόσο, είναι ένα εξαιρετικό μέρος για να πυροβολήσετε τον εαυτό σας στο πόδι (ή στο κεφάλι) αν δεν είστε προσεκτικοί. Νόμιζα ότι ήξερα τι συνέβαινε, αλλά δεν το ήξερα.

Η προτιμώμενη επιλογή, η αποθήκευση των singleton σας στο HttpContext.Current.Items, είναι απλή και ασφαλής, αλλά συνδέει το εν λόγω singleton με τη χρήση σε μια ASP.Net εφαρμογή. Εάν το singleton είναι κάτω στα αντικείμενα της επιχείρησής σας, αυτό δεν είναι ιδανικό. Ακόμα κι αν τυλίξετε την ιδιότητα πρόσβασης σε μια δήλωση if

... τότε πρέπει ακόμα να αναφέρετε το System.Web από αυτό το συγκρότημα, το οποίο τείνει να ενσωματώνει περισσότερα αντικείμενα «webby» σε λάθος μέρος.

Οι εναλλακτικές λύσεις είναι να χρησιμοποιήσετε ένα στατικό μέλος [ThreadStatic], τοπική αποθήκευση Thread (που ισοδυναμεί σχεδόν με το ίδιο πράγμα) ή CallContext.

Τα προβλήματα με το [ThreadStatic] είναι καλά τεκμηριωμένα, αλλά για να συνοψίσουμε:
Οι εκκινητές πεδίου ενεργοποιούνται μόνο στο πρώτο νήμα
Τα δεδομένα ThreadStatic χρειάζονται ρητό καθαρισμό (π.χ. στο EndRequest), επειδή ενώ το νήμα είναι προσβάσιμο, τα δεδομένα ThreadStatic δεν θα είναι GC'd, επομένως ενδέχεται να διαρρέετε πόρους.
Τα δεδομένα ThreadStatic είναι καλά μόνο μέσα σε ένα αίτημα, επειδή το επόμενο αίτημα μπορεί να έρθει σε διαφορετικό νήμα και να λάβει τα δεδομένα κάποιου άλλου.
Ο Scott Hanselman έχει δίκιο, ότι το ThreadStatic δεν παίζει καλά με ASP.Net, αλλά δεν εξηγεί πλήρως γιατί.

Η αποθήκευση στο CallContext ανακουφίζει ορισμένα από αυτά τα προβλήματα, καθώς το περιβάλλον εξαφανίζεται στο τέλος του αιτήματος και το GC θα συμβεί τελικά (αν και μπορείτε ακόμα να διαρρεύσετε πόρους μέχρι να συμβεί το GC εάν αποθηκεύετε αναλώσιμα). Επιπλέον, το CallContext είναι ο τρόπος με τον οποίο αποθηκεύεται το HttpContext, επομένως πρέπει να είναι εντάξει, σωστά;. Ανεξάρτητα από αυτό, θα σκεφτόσασταν (όπως έκανα εγώ) ότι με την προϋπόθεση ότι καθαρίζατε τον εαυτό σας στο τέλος κάθε αιτήματος, όλα θα ήταν καλά:
«Εάν αρχικοποιήσετε τη μεταβλητή ThreadStatic στην αρχή του αιτήματος και χειριστείτε σωστά το αντικείμενο αναφοράς στο τέλος του αιτήματος, θα διακινδύνευα να ισχυριστώ ότι δεν θα συμβεί τίποτα κακό

«Τώρα,Μπορεί να κάνω λάθος. Το CLR μπορεί να σταματήσει να φιλοξενεί ένα νήμα στα μισά του δρόμου, να σειριοποιήσει τη στοίβα του κάπου, να του δώσει μια νέα στοίβα και να το αφήσει να αρχίσει να εκτελείται。 Αμφιβάλλω βαθιά γι' αυτό. Υποθέτω ότι είναι κατανοητό ότι το hyperthreading θα δυσκόλευε επίσης τα πράγματα, αλλά αμφιβάλλω επίσης. ”

Τζεφ Νιούσομ


«Εάν αρχικοποιήσετε μια μεταβλητή ThreadStatic στην αρχή ενός αιτήματος και απορρίψετε σωστά το αναφερόμενο αντικείμενο στο τέλος του αιτήματος, θα βγω έξω και θα ισχυριστώ ότι τίποτα Το κακό θα συμβεί. Είστε ψύχραιμοι ακόμη και μεταξύ των πλαισίων στο ίδιο AppDomain

«Τώρα, μπορεί να κάνω λάθος σε αυτό. Το clr θα μπορούσε ενδεχομένως να σταματήσει ένα διαχειριζόμενο νήμα στη μέση της ροής, να σειριοποιήσει τη στοίβα του κάπου, να του δώσει μια νέα στοίβα και να το αφήσει να αρχίσει να εκτελείται. Αμφιβάλλω σοβαρά. Υποθέτω ότι είναι κατανοητό ότι το hyperthreading δυσκολεύει επίσης τα πράγματα, αλλά αμφιβάλλω επίσης γι' αυτό».
Τζεφ Νιούσομ
Ενημέρωση: Αυτό είναι παραπλανητικό. Θα εξηγήσω περαιτέρω αργότερα ότι αυτή η εναλλαγή νημάτων μπορεί να συμβεί μόνο μεταξύ του BeginRequest και του Page_Load, αλλά η αναφορά του Jef δημιουργεί μια πολύ ισχυρή εικόνα που δεν κατάφερα να διορθώσω αμέσως.

Update: This was the misleading bit. I do explain further later on that this thread-swap can only happen between the BeginRequest and the Page_Load, but Jef's quote creates a very powerful image I failed to immediately correct. My bad.
Έτσι, κάποια στιγμή, ASP.NET αποφασίσουμε ότι υπάρχουν πάρα πολλά νήματα I/O που επεξεργάζονται άλλα αιτήματα. […] Δέχεται μόνο αιτήματα και τα τοποθετεί σε ουρά σε ένα εσωτερικό αντικείμενο ουράς εντός ASP.NET χρόνου εκτέλεσης. Στη συνέχεια, μετά την ουρά, το νήμα I/O θα ζητήσει ένα νήμα εργασίας και, στη συνέχεια, το νήμα I/O θα επιστρέψει στο χώρο συγκέντρωσης του. […] Επομένως, ASP.NET θα αφήσει αυτόν τον εργαζόμενο να χειριστεί το αίτημα. Θα το φέρει σε ASP.NET χρόνο εκτέλεσης, όπως ακριβώς θα έκανε το νήμα I/O σε χαμηλό φορτίο.

Έτσι ASP.NET κάποια στιγμή αποφασίζει ότι υπάρχουν πάρα πολλά νήματα I/O που επεξεργάζονται άλλα αιτήματα. [...] Απλώς παίρνει το αίτημα και το τοποθετεί στην ουρά σε αυτό το εσωτερικό αντικείμενο ουράς εντός του ASP.NET χρόνου εκτέλεσης. Στη συνέχεια, αφού τοποθετηθεί στην ουρά, το νήμα I/O θα ζητήσει ένα νήμα εργασίας και, στη συνέχεια, το νήμα I/O θα επιστρέψει στο χώρο συγκέντρωσης του. [...] Έτσι ASP.NET θα ζητήσετε από αυτό το νήμα εργαζόμενου να επεξεργαστεί το αίτημα. Θα το μεταφέρει στο ASP.NET χρόνο εκτέλεσης, όπως ακριβώς θα είχε το νήμα I/O υπό χαμηλό φορτίο.

Τώρα πάντα το ήξερα, αλλά νομίζω ότι συνέβη πολύ νωρίς και δεν με ένοιαζε. Ωστόσο, φαίνεται να κάνω λάθος. Είχαμε ένα πρόβλημα στην εφαρμογή ASP.Net όπου ένας χρήστης έκανε κλικ σε έναν σύνδεσμο αφού έκανε κλικ σε έναν άλλο σύνδεσμο και η εφαρμογή μας είχε μια μηδενική εξαίρεση αναφοράς σε ένα από τα singleton (χρησιμοποίησα το CallContext αντί για το ThreadStatic για το singleton, αλλά αποδείχθηκε άσχετο).

Έκανα κάποια έρευνα για το πώς ακριβώς λειτουργούν ASP.Net νήματα και έλαβα αντικρουόμενες απόψεις μεταμφιεσμένες σε γεγονότα (τα αιτήματα είναι ευέλικτα στα αιτήματα, ενώ τα αιτήματα είναι αγκυρωμένα σε νήματα κατά τη διάρκεια της ζωής τους), οπότε αντέγραψα το πρόβλημά μου σε μια δοκιμαστική εφαρμογή με αργή σελίδα (κοιμάται για ένα δευτερόλεπτο) και γρήγορη σελίδα. Κάνω κλικ στον σύνδεσμο προς την αργή σελίδα και πριν επιστρέψει η σελίδα, κάνω κλικ στον σύνδεσμο προς τη γρήγορη σελίδα. Το αποτέλεσμα (log4net dump του τι συμβαίνει) με εξέπληξε.

Η έξοδος δείχνει ότι για το δεύτερο αίτημα, το συμβάν BeginRequest και ο κατασκευαστής σελίδας στη διοχέτευση HttpModule ενεργοποιούνται σε ένα νήμα, αλλά page_Load σε ένα άλλο. Το δεύτερο νήμα έχει ήδη μετεγκαταστήσει το HttpContext από το πρώτο νήμα, αλλά όχι το CallContext ή το ThreadStatic (σημείωση: δεδομένου ότι το ίδιο το HttpContext είναι αποθηκευμένο στο CallContext, αυτό σημαίνει ότι ASP.Net μεταφέρει ρητά το HttpContext). Ας το ξαναπούμε:


Τώρα πάντα το ήξερα αυτό, αλλά υπέθεσα ότι συνέβη αρκετά νωρίς στη διαδικασία που δεν με ένοιαζε. Φαίνεται όμως ότι έκανα λάθος. Αντιμετωπίζουμε ένα πρόβλημα στην εφαρμογή ASP.Net όπου ο χρήστης κάνει κλικ σε έναν σύνδεσμο αμέσως μετά το κλικ σε έναν άλλο και η εφαρμογή μας ανατινάζεται με μια μηδενική εξαίρεση αναφοράς για ένα από τα singleton μας (χρησιμοποιώ CallContext όχι ThreadStatic για το singleton, αλλά αποδεικνύεται ότι δεν έχει σημασία).

Έκανα λίγη έρευνα για το πώς ακριβώς το ASP. Το threading του Net λειτουργεί και έχει αντικρουόμενες απόψεις που μεταμφιέζονται σε γεγονότα (τα αιτήματα είναι ευέλικτα μέσα σε ένα αίτημα έναντι αιτημάτων που είναι καρφιτσωμένα σε ένα νήμα για όλη τους τη ζωή) οπότε αναπαρήγαγα το δικό μου Πρόβλημα σε μια δοκιμαστική εφαρμογή με αργή σελίδα (κοιμάται για ένα δευτερόλεπτο) και γρήγορη σελίδα. Κάνω κλικ στον σύνδεσμο για την αργή σελίδα και πριν επιστρέψει η σελίδα κάνω κλικ στον σύνδεσμο για τη γρήγορη σελίδα. Τα αποτελέσματα (μια χωματερή του log4net για το τι συμβαίνει) με εξέπληξαν.

Αυτό που δείχνει η έξοδος είναι ότι - για το δεύτερο αίτημα - τα συμβάντα BeginRequest στη διοχέτευση HttpModule και ο κατασκευαστής σελίδων ενεργοποιούνται σε ένα νήμα, αλλά το Page_Load ενεργοποιείται σε ένα άλλο. Στο δεύτερο νήμα έχει μετεγκατασταθεί το HttpContext από το πρώτο, αλλά όχι το CallContext ή το ThreadStatic (Σημείωση: δεδομένου ότι το ίδιο το HttpContext είναι αποθηκευμένο στο CallContext, αυτό σημαίνει ότι ASP.Net είναι μετεγκατάσταση του HttpContext απέναντι). Ας το ξεκαθαρίσουμε ξανά:

  • Η εναλλαγή νημάτων πραγματοποιείται μετά τη δημιουργία του IHttpHandler
  • Μετά την εκτέλεση του αρχικοποιητή πεδίων και του κατασκευαστή της σελίδας
  • Μετά από οποιαδήποτε συμβάντα τύπου BeginRequest, AuthenticateRequest, AquireSessionState που χρησιμοποιούνται από το Global.ASA/IHttpModules.
  • Μόνο το HttpContext μετεγκαθίσταται στο νέο νήμα



Ο διακόπτης νήματος εμφανίζεται μετά τη δημιουργία του IHttpHandler
Μετά την εκτέλεση των αρχικοποιητών πεδίων και του κατασκευαστή της σελίδας
Μετά από οποιαδήποτε συμβάντα τύπου BeginRequest, AuthenticateRequest, AquireSessionState που χρησιμοποιούν τα Global.ASA / IHttpModules.
Μόνο το HttpContext μετεγκαθίσταται στο νέο νήμα

Αυτό είναι ένα σημαντικό PITA γιατί από ό,τι έχω δει σημαίνει ότι η μόνη επιλογή επιμονής για τη συμπεριφορά της κλάσης "ThreadStatic" στο ASP.Net είναι η χρήση του HttpContext. Έτσι, για τα αντικείμενα της επιχείρησής σας, είτε συνεχίζετε να χρησιμοποιείτε το if(HttpContext.Current!). =null) και αναφορά System.Web (μπλιαχ), ή πρέπει να βρείτε κάποιο είδος μοντέλου παρόχου για στατική επιμονή, το οποίο πρέπει να ρυθμιστεί πριν αποκτήσετε πρόσβαση σε αυτά τα singletons. Διπλή ναυτία.

Παρακαλώ πείτε ότι αυτό δεν ισχύει.

Παράρτημα: Πλήρες ημερολόγιο:


Αυτό είναι ένα σημαντικό PITA, γιατί από όσο μπορώ να δω σημαίνει ότι η μόνη επιλογή επιμονής για τη συμπεριφορά του 'ThreadStatic' σε ASP.Net είναι η χρήση του HttpContext. Έτσι, για τα αντικείμενα της επιχείρησής σας, είτε έχετε κολλήσει με το if(HttpContext.Current!=null) και την αναφορά System.Web (μπλιαχ) είτε πρέπει να βρείτε κάποιο είδος μοντέλου παρόχου για το δικό σας στατική επιμονή, η οποία θα πρέπει να ρυθμιστεί πριν από το σημείο πρόσβασης σε οποιοδήποτε από αυτά τα singleton. Διπλό μπλιαχ.

Παρακαλώ κάποιος να πει ότι δεν είναι έτσι.

Appendix: That log in full:
[3748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:05,239 ΑΣΠ. Global_asax. Application_BeginRequest() - BEGIN /ConcurrentRequestsDemo/SlowPage.aspx
[3748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:05,239 ΑΣΠ. Global_asax. Application_BeginRequest() - threadid=, threadhash=, threadhash(τώρα)=97, calldata=
[3748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:05,249 ΑΣΠ. SlowPage_aspx.. ctor() - threadid=3748, threadhash=(cctor)97, threadhash(now)=97, calldata=3748, logicalcalldata=3748
[3748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:05,349 ΑΣΠ. SlowPage_aspx. Page_Load() - threadid=3748, threadhash=(cctor)97, threadhash(now)=97, calldata=3748, logicalcalldata=3748
[3748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:05,349 ΑΣΠ. SlowPage_aspx. Page_Load() - Αργή αδράνεια σελίδας....

[2720] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:05,669 ΑΣΠ. Global_asax. Application_BeginRequest() - BEGIN /ConcurrentRequestsDemo/FastPage.aspx
[2720] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:05,679 ASP. Global_asax. Application_BeginRequest() - threadid=, threadhash=, threadhash(τώρα)=1835, calldata=
[2720] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:05,679 ASP. FastPage_aspx.. ctor() - threadid=2720, threadhash=(cctor)1835, threadhash(τώρα)=1835, calldata=2720, logicalcalldata=2720, threadstatic=2720

[3748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:06,350 ΑΣΠ. SlowPage_aspx. Page_Load() - Αργή αφύπνιση σελίδας....
[3748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:06,350 ΑΣΠ. SlowPage_aspx. Page_Load() - threadid=3748, threadhash=(cctor)97, threadhash(now)=97, calldata=3748, logicalcalldata=3748
[3748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:06,350 ΑΣΠ. Global_asax. Application_EndRequest() - threadid=3748, threadhash=97, threadhash(now)=97, calldata=3748
[3748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:06,350 ΑΣΠ. Global_asax. Application_EndRequest() - ΤΕΛΟΣ /ConcurrentRequestsDemo/SlowPage.aspx

[4748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:06,791 ΑΣΠ. FastPage_aspx. Page_Load() - threadid=2720, threadhash=(cctor)1835, threadhash(now)=1703, calldata=, logicalcalldata=, threadstatic=
[4748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:06,791 ΑΣΠ. Global_asax. Application_EndRequest() - threadid=2720, threadhash=1835, threadhash(τώρα)=1703, calldata=
[4748] ΠΛΗΡΟΦΟΡΊΕΣ 11:10:06,791 ΑΣΠ. Global_asax. Application_EndRequest() - ΤΕΛΟΣ /ConcurrentRequestsDemo/FastPage.aspx
Το κλειδί είναι τι συμβαίνει όταν ενεργοποιείται η Page_Load του FastPage. Το ThreadID είναι 4748, αλλά το ThreadID που αποθήκευσα στο HttpContext του ctor είναι 2720. Ο κωδικός κατακερματισμού για τα λογικά νήματα είναι 1703, αλλά ο κωδικός κατακερματισμού που αποθηκεύω στο ctor είναι 1835. Όλα τα δεδομένα που αποθήκευσα στο CallContext λείπουν (ακόμη και τα δεδομένα με την ένδειξη ILogicalThreadAffinnative), αλλά το HttpContext εξακολουθεί να υπάρχει. Όπως θα περίμενε κανείς, το ThreadStatic μου έχει φύγει επίσης.

Το βασικό κομμάτι είναι τι συμβαίνει όταν ενεργοποιείται η Page_Load του FastPage. Το ThreadID είναι 4748, αλλά το threadID που αποθήκευσα στο HttpContext στο ctor είναι 2720. Ο κωδικός κατακερματισμού για το λογικό νήμα είναι 1703, αλλά αυτός που αποθήκευσα στο ctor είναι 1835. Όλα τα δεδομένα που αποθήκευσα στο CallContext έχουν φύγει (ακόμα και αυτά με την ένδειξη ILogicalThreadAffinative), αλλά το HttpContext εξακολουθεί να υπάρχει. Όπως θα περίμενε κανείς, το ThreadStatic μου έχει φύγει επίσης.
(Τέλος)




Προηγούμενος:.NET/C# συλλογή Any() ή Count() που είναι πιο γρήγορη
Επόμενος:Πώς το Lazy in C# διατηρεί τα νήματα ασφαλή

σχετικές αναρτήσεις

 Σπιτονοικοκύρης| Δημοσιεύτηκε στις 30/6/2023 8:35:23 μ.μ. |
 Σπιτονοικοκύρης| Δημοσιεύτηκε στις 2/7/2023 9:59:06 π.μ. |
CallContext

Χώρος ονομάτων: System.Runtime.Remoting.Messaging
Πληκτρολογήστε πλήρως προσδιορισμένο όνομα: System.Runtime.Remoting.Messaging.CallContext

Σκοπός: Για την παροχή ενός συνόλου χαρακτηριστικών που μεταβιβάζονται μαζί με τη διαδρομή του κώδικα εκτέλεσης, με απλά λόγια: για την παροχή της δυνατότητας μετάδοσης δεδομένων στη διαδρομή εκτέλεσης του κώδικα με νήματα (πολλαπλών νημάτων/μονού νήματος).
μέθοδοςπεριγραφήΕάν μπορεί να χρησιμοποιηθεί σε περιβάλλον πολλαπλών νημάτων
Σύνολο δεδομένωνΑποθηκεύστε ένα δεδομένο αντικείμενο και συσχετίστε το με ένα καθορισμένο όνομα.όχι
Λήψη δεδομένωνΑνακτήστε το αντικείμενο με το καθορισμένο όνομα από το System.Runtime.Remoting.Messaging.CallContextόχι
LogicalSetDataΑποθηκεύστε ένα δεδομένο αντικείμενο στο πλαίσιο μιας λογικής κλήσης και συσχετίστε το με ένα καθορισμένο όνομα.είμαι
LogicalGetDataΑνάκτηση αντικειμένων με καθορισμένα ονόματα από το περιβάλλον λογικής κλήσης.είμαι
FreeNamedDataSlotΑδειάστε τις υποδοχές δεδομένων με το καθορισμένο όνομα.είμαι
HostContextΛάβετε ή ορίστε το περιβάλλον κεντρικού υπολογιστή που σχετίζεται με το τρέχον νήματα. Στο περιβάλλον ιστού, ισούται με το System.Web.HttpContext.Currentόχι


Αποκήρυξη:
Όλο το λογισμικό, το υλικό προγραμματισμού ή τα άρθρα που δημοσιεύονται από το Code Farmer Network προορίζονται μόνο για μαθησιακούς και ερευνητικούς σκοπούς. Το παραπάνω περιεχόμενο δεν θα χρησιμοποιηθεί για εμπορικούς ή παράνομους σκοπούς, άλλως οι χρήστες θα υποστούν όλες τις συνέπειες. Οι πληροφορίες σε αυτόν τον ιστότοπο προέρχονται από το Διαδίκτυο και οι διαφορές πνευματικών δικαιωμάτων δεν έχουν καμία σχέση με αυτόν τον ιστότοπο. Πρέπει να διαγράψετε εντελώς το παραπάνω περιεχόμενο από τον υπολογιστή σας εντός 24 ωρών από τη λήψη. Εάν σας αρέσει το πρόγραμμα, υποστηρίξτε γνήσιο λογισμικό, αγοράστε εγγραφή και λάβετε καλύτερες γνήσιες υπηρεσίες. Εάν υπάρχει οποιαδήποτε παραβίαση, επικοινωνήστε μαζί μας μέσω email.

Mail To:help@itsvse.com