Greifen Sie auf HttpContext.Current aus verschiedenen Threads zu

Ich habe eine C # ASP.NET-Anwendung, die etwa 25 verschiedene Threads startet, die einige Methoden in einer class namens SiteCrawler.cs ausführen.

In HttpContext.Current.Session möchte ich das Ergebnis der vom Benutzer durchgeführten Suche speichern und es dem Benutzer präsentieren, wenn alle Threads beendet sind. Mein Problem ist, dass das HttpContext.Current Objekt in den erzeugten Threads null ist, da es dort nicht vorhanden ist.

Welche anderen Optionen habe ich, um Benutzer / Sitzungsspezifische Daten zu speichern, ohne Sitzung zu verwenden, aufgrund der Einschränkungen, wenn die Anwendung Multithread ist?

Ich habe versucht, jeden Zentimeter von Stackoverflow zu suchen, um eine Lösung zu finden, aber ohne Glück ….

In meiner Anwendung gibt es viel Code, der HttpContext.Current und ich kann diesen Code nicht ändern.

worker.DoWork() aus dem folgenden Beispiel verwendet diesen Code. Und ich musste es in einem separaten Thread laufen lassen.

Ich kam zu folgender Lösung:

  HttpContext ctx = HttpContext.Current; Thread t = new Thread(new ThreadStart(() => { HttpContext.Current = ctx; worker.DoWork(); })); t.Start(); // [... do other job ...] t.Join(); 

Werfen Sie einen Blick auf diesen Artikel von Fritz Onion: Verwenden Sie Threads und erstellen Sie asynchrone Handler in Ihrem Server-Side Web Code . Es ist ziemlich lang, aber Ihre Anforderung ist nicht zu trivial.

Auch K. Scott Allen hat einen etwas kürzeren Artikel über dieses Thema veröffentlicht: Mit HttpContext.Current arbeiten

@Rory hat oben einen Kommentar gemacht, dass bestimmte Objekte im HttpContext Null werden, auch wenn Sie sie in den Thread übergeben. Dies ist mir mit der User Eigenschaft passiert. Stattdessen können Sie den Benutzer wie folgt in den Thread CurrentPrincipal kopieren:

Speichern Sie den Benutzer im Steuerungskontext:

  _user = HttpContext.Current.User; var processThread = new Thread(() => ThreadedCode()); processThread.Start(); 

Setzen Sie im Thread den Benutzer “Thread”:

  private static void ThreadedCode() { // Workaround for HttpContext.Current.User being null. // Needed for CreatedBy and RevisedBy. Thread.CurrentPrincipal = _user; 

Beachten Sie, dass der HttpContext nur für die Lebensdauer der Anfrage verfügbar ist. Der Thread wird potenziell länger als die Anfrage leben, weshalb Sie wahrscheinlich einen Thread benötigen! 🙂

Fügen Sie einfach den HttpContext.Current zum Konstruktor Ihrer class SiteCrawler.cs hinzu

 public class SiteCrawler { HttpContext context = HttpContext.Current; public void Method() { context.WhateverYouWant } } 

Sie können es in der database speichern und dann können Sie den Browser des Benutzers aktualisieren oder Ajax verwenden oder den neuen Signalgeber verwenden, um zu überprüfen, ob das Ergebnis bereits in db geschrieben ist. ich hoffe es hilft.