2013-01-08 15 views
10

Chcę zapewnić, że moja strona internetowa będzie mogła być hostowana w chmurze w przyszłości, a także, że może obsłużyć wiele żądań.ASP.NET MVC Jak bezpieczne są zmienne statyczne?

Jak bezpieczne są zmienne statyczne?

Czy są one niebezpieczne, ponieważ oddzielne żądania od oddzielnych użytkowników faktycznie udostępniają te statyczne zmienne? A może dlatego, że jeśli przenosisz stronę na wątki/sharding lub podobne, (aby poradzić sobie z dużymi obciążeniami), wątki dzielą się statycznymi zmiennymi?

Głównie Mam klasy pomocnicze z właściwościami statycznymi, czy powinienem zmienić tę architekturę, aby zamiast tego utworzyć instancję każdej klasy i uzyskać dostęp do instancji?

np Oto próbka tego, co robię:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using Mvc.Mailer; 

namespace MVCWebsite.Helpers 
{ 
     public class AppSettings 
     { 
       public static void OnAppInit() 
       { 
         //General 
         AppName = "MyApp"; 
         DesktopBaseURLs = new Dictionary<string, string>(); 
         DesktopBaseURLs.Add("dev", "localhost:50560"); 
         DesktopBaseURLs.Add("test", "www.test.whatever.com"); 
         DesktopBaseURLs.Add("live", "www.whatever.com"); 
         MobileBaseURLs = new Dictionary<string, string>(); 
         MobileBaseURLs.Add("dev", "m.local.whatever.com"); 
         MobileBaseURLs.Add("test", "m.test.whatever.com"); 
         MobileBaseURLs.Add("live", "m.whatever.com"); 

         //Emails 
         EmailHostName = AppName + ".com"; //For the moment atleast 
         NoReplyEmailAddress = "[email protected]" + EmailHostName.ToLower(); 
         SupportEmailAddress = "[email protected]" + EmailHostName.ToLower(); 
         ErrorEmailAddress = "[email protected]" + EmailHostName.ToLower(); 

         //Resources 
         TempFileURL = "/content/temp/"; 
         UserDataURL = "/content/user-content/"; 
         ProfilePicturesURL = UserDataURL + "profile-pictures/"; 

         var a = GlobalHelper.GetURLAsServerPath(ProfilePicturesURL); 
         var b = a; 

       } 

       //General 
       public static string AppName { get; set; } 
       public static Dictionary<string, string> DesktopBaseURLs; 
       public static Dictionary<string, string> MobileBaseURLs; 

       //Emails 
       public static string EmailHostName { get; set; } 
       public static string NoReplyEmailAddress { get; set; } 
       public static string SupportEmailAddress { get; set; } 
       public static string ErrorEmailAddress { get; set; } 

       //Resources 
       public static string UserDataURL { get; set; } 
       public static string TempFileURL { get; set; } 
       public static string ProfilePicturesURL { get; set; } 

       //Methods 
       public static void SetAppURL() 
       { 

       } 
     } 
} 
+0

Obowiązują te same zasady ... statyczny jest udostępniany w domenie aplikacji. W przypadku współdzielonych danych konfiguracji (jak w twoim przykładzie) może to być dokładnie to, czego potrzebujesz, ale staraj się tylko zainicjować tylko jeden raz i z jednego wątku. –

Odpowiedz

15

Twój kod nie jest bezpieczny dla wątków. Udostępniasz zmienne statyczne między wieloma żądaniami, które potencjalnie mogą być wykonywane przez wiele wątków. Należy pamiętać, że klasa Dictionary<TKey, TValue>, której używasz jako pamięci bazowej, nie jest klasą bezpieczną dla wątków, co oznacza, że ​​Twój kod może potencjalnie bardzo się zepsuć, jeśli spróbujesz połączyć się z metodą OnAppInit jednocześnie z wielu wątków. Jeśli z drugiej strony wywołujesz tę metodę statyczną tylko jeden raz w swoim zdarzeniu Application_Start (które gwarantowane jest uruchamianie tylko raz z pojedynczego wątku), możesz go tam bezpiecznie używać.

To powiedzenie, że zmienne statyczne i metody są generalnie złym pomysłem w aplikacjach, nie są prawdziwe. Jest to zły pomysł, jeśli nie wiesz, jak z nich korzystać poprawnie, lub jeśli nie wiesz, jak zsynchronizować dostęp do nich, jeśli potrzebujesz tego do zrobienia z równoczesnych wątków. Pisanie kodu zabezpieczającego przed wątkami jest bardzo trudnym tematem i jeśli masz obawy, aby to zrobić źle (kto nie pisze podczas pisania aplikacji wielowątkowych, takich jak aplikacje ASP.NET?), Po prostu nie współdziel tego stanu. Użyj dobrze znane miejsca do tego w aplikacji ASP.NET:

  • Backend (może być relacyjna baza danych, na przykład)
  • State Zastosowanie
  • Cache
  • HTTP State Kontekst
  • Session State
  • ciasteczka klienta

Te miejsca są SPECYFIK lly zaprojektowany do przechowywania stanu w aplikacji ASP.NET (z wyjątkiem pierwszego oczywiście, który można wykorzystać w dowolnym typie aplikacji).

+0

czy mógłbyś wyjaśnić nieco więcej ... co masz na myśli "twój kod mógłby potencjalnie bardzo się zepsuć, jeśli spróbujesz połączyć się z metodą OnAppInit jednocześnie z wielu wątków"? Co dokładnie mogło pójść nie tak z tą metodą? – Dmitry

+3

Ta metoda modyfikuje lokalną zmienną statyczną, która jest Słownikiem typu. Jak powiedziałem w mojej odpowiedzi, ten typ nie jest ** bezpieczny dla wątków **.Na przykład pierwszy wątek przydzieli pewną wartość do słownika i zacznie dodawać do niego wartości, gdy inny wątek po prostu przydzieli go do nowego słownika tracąc wszystkie wartości, które do tej pory mógł zapisać pierwszy wątek. Ten kod nigdy nie powinien być wywoływany z wielu wątków. –

+0

Jeszcze raz dziękuję Darin! Następnie albo zapiszę instancje, które utworzę w obiekcie globalnym dla łatwego dostępu, albo będę miał statyczne metody Get() w każdej klasie, która zwraca jedyną instancję. To powinno to naprawić. :) – Baconbeastnz

2

zmiennych statycznych zostaną podzielone między żądaniami. Ponadto zostaną one zainicjowane po uruchomieniu aplikacji, , więc jeśli AppDomain, a tym samym aplikacja zostanie ponownie uruchomiona, ich wartości zostaną ponownie zainicjowane.