2013-02-25 2 views
4

J'ai implémenté un travail qui ajoute des valeurs à l'état de session dans un thread. Je voudrais que ces valeurs soient disponibles en dehors du Thread (évidemment).Le mode session "ServerState" ne gère pas la session dans un thread correctement

Les informations ajoutées à la session sont disponibles en dehors de la session sans aucun problème lorsque le mode d'état de session est "InProc". Lorsque le mode d'état de session est sur "StateServer", le comportement est différent. Fondamentalement, les valeurs définies à l'intérieur du thread sont conservées parfois et parfois pas. Cela me semble aléatoire.

Voici un code qui reproduit le problème.

public partial class _Default : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
    } 

    protected void store_Click(object sender, EventArgs e) 
    { 
     // Set the session values to default. 
     Session["Test1"] = "No"; 
     Session["Test2"] = "No"; 

     // Set the Test1 session value in the thread. 
     ThreadObject threadObject = new ThreadObject() { Username = Page.User.Identity.Name, SessionState = Session }; 
     worker = new Thread(new ParameterizedThreadStart(Work)); 
     worker.Start(threadObject); 

     // Set the Test2 session value in this thread just to compare. 
     Session["Test2"] = "Yes"; 
    } 

    protected void print_Click(object sender, EventArgs e) 
    { 
     // Print out the Session values. 
     label1.Text = string.Empty; 
     label1.Text += "Inside Thread: " + Session["Test1"] + ", \n"; 
     label1.Text += "Outside: " + Session["Test2"] + "\n"; 
    } 

    private static Thread worker; 

    public static void Work(object threadObject) 
    { 
     // Retrieve the Session object and set the Test2 value. 
     ThreadObject threadObject1 = (ThreadObject)threadObject; 
     HttpSessionState currentSession = threadObject1.SessionState; 
     currentSession["Test1"] = "Yes"; 
    } 
} 

public class ThreadObject 
{ 
    public string Username { get; set; } 
    public HttpSessionState SessionState { get; set; } 
} 

Le code ci-dessus fonctionne très bien avec le mode SessionState = "InProc", mais est aléatoire:

<sessionState mode="StateServer" 
    stateConnectionString="tcpip=localhost:42424" 
    cookieless="false" 
    timeout="20"/> 

Toutes les idées?

EDIT: Ainsi, selon les commentaires ci-dessous, le thread doit se terminer avant la fin de la demande (thread principal), sinon tout élément ajouté à la session est perdu. En effet, à la fin du thread principal, la session est sérialisée et envoyée au magasin de données (Out of Process ou SQL Server).

Répondre

1

Je pense que c'est un problème de synchronisation - il n'y a aucune garantie que votre thread de travail aura été exécuté au moment où vous définissez les valeurs de votre label. Il faut quelques MS pour créer et lancer la bande de roulement. D'ici là, le reste de votre fil principal a probablement terminé. Vous pouvez tester cela en mettant la sortie de débogage et en voyant l'ordre dans lequel votre code est exécuté.

Si vous devez garantir que le code de votre thread s'exécute (ce qui élimine le besoin d'un thread) - vous pouvez utiliser une méthode de thread WaitOne() pour que votre thread principal attende le thread de travail à retourner. Mais en fonction d'une valeur définie dans un thread pour être disponible dans un processus parallèle est risqué.

De plus - À mon humble avis, je n'utiliserais pas de threads dans les applications ASP.NET - Je crois que le consensus est qu'ils sont un peu dangereux. J'ai vu des plantages d'applications à cause d'un mauvais code dans un thread engendré.

+0

Je pense que vous avez raison avec la condition _race_, mais le thread peut aussi être important pour ASP.NET. Il n'y a rien de mal, si mis en œuvre et utilisé correctement. Laisser l'ASP.NET Main-Thread attendre sur n'importe quoi rendra le thread disponible pour traiter d'autres requêtes - C'est la raison pour laquelle MVC autorise Task . – TGlatzer

+0

Je ne peux pas être en désaccord - même si votre mise en garde - "si correctement implémenté" semble être un problème commun :-) – Ripside

+0

Hey, bien le code de réglage de l'étiquette fait partie d'un clic, et j'ai attendu plus de quelques secondes avant tenter d'imprimer les valeurs de session dans l'étiquette. Donc, je ne suis pas si sûr que c'est un problème de synchronisation. Si vous appuyez plusieurs fois sur le bouton print_Click, le thread peut éventuellement définir sa valeur dans la session. – Ivan

Questions connexes