Problem with ThreadStatic from C #

0

I have a system where its authentication holds a token in a ThreadStatic property. It turns out that Monday, he started distributing the tokens incorrectly (after updating the windows server).

  

I made the application below to test the scenario

public class HomeController : Controller {
    [ThreadStatic]
    public static String texto;

    public String teste(String valor) {
        if(valor != null && !valor.equals("")) {
             texto = valor;
        }
        return texto;
    }
}
  

Scenery

If I call the URL http://localhost/home/teste?valor=oi I get the result hi. If I call the same method http://localhost/home/teste without passing the attribute value time it returns me empty, time it returns me filled and if I call again passing as value tchau it will get me returning this value in a random way. Is this behavior normal with ThreadStatic or might it have modified something in the .NET update?

Thank you.

    
asked by anonymous 31.10.2018 / 19:22

2 answers

0

According to Microsoft Docs , the ThreadStatic attribute "indicates that the value of a static field will be unique for each thread. "

And from what I read in this article from a Microsoft blog:

  

ASP.NET Thread Usage on IIS 7.5, IIS 7.0, and IIS 6.0 - Thomas Marquardt's Blog
link

I understand that requests in ASP.NET can use the same thread but can also be executed on different threads. So, it seems to me that what is happening is that in your tests some threads are created, and each has its value for static field HomeController.texto , because of the ThreadStatic attribute.

Here in this discussion in an MSDN forum:

  

[ThreadStatic] and the threadpool - MSDN Forums

Moderator Reed Copsey Jr suggests using the ThreadLocal<T> ( class documentation ), rather than the ThreadStatic attribute. And, using the documentation example, you can even create a new static field in your HomeController class to see if the threads are even different:

public class HomeController : Controller {
   [ThreadStatic] public static String texto;

   // Variável Thread-Local que produz um nome para uma thread.
   public static readonly ThreadLocal<string> NomeThread = new ThreadLocal<string>(() =>
   {
      return $"Thread #{Thread.CurrentThread.ManagedThreadId}";
   });

   public String teste(String valor) {
      // Substitui as duas verificações anteriores pelo método String.IsNullOrEmpty().
      if(String.IsNullOrEmpty(valor)) {
         texto = valor;
      }
      return $"Texto: '{texto}' / Nome da thread: '{NomeThread}'";
   }
}

You could also simply delete the ThreadStatic attribute of this field if you wanted a single value for the entire application, because according to that response of the EN , static fields are thread-safe :

  

C # - Thread safety on readonly static field initialisation - Stack overflow
link

But why do not you leave this field as a normal field, rather than static? That way each object HomeController would have its value, would not it?

    
01.11.2018 / 13:20
0

Yes, this is normal behavior

You do not control which thread your Controller is running. Each request can have a new thread, a repeated thread, and you have no way of knowing.

How to solve

To save a specific data for a user, you use sessions .

    
01.11.2018 / 22:14