14

将来的には、自分の Web サイトをクラウドでホストできるようにし、多くのリクエストを処理できるようにしたいと考えています。

静的変数はどれくらい安全ですか?

別々のユーザーによる別々のリクエストが実際にこれらの静的変数を共有しているため、それらは安全ではありませんか? それとも、(高負荷を処理するために) スレッド/シャーディングなどにサイトを分散させると、スレッドが静的変数を共有しているためでしょうか?

主に静的プロパティを持つヘルパー クラスがありますが、代わりに各クラスのインスタンスを作成してインスタンスにアクセスするように、このアーキテクチャを変更する必要がありますか?

EGこれが私がやっていることのサンプルです:

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 = "no-reply@" + EmailHostName.ToLower();
                        SupportEmailAddress = "support@" + EmailHostName.ToLower();
                        ErrorEmailAddress = "errors@" + 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()
                {

                }
        }
}
4

2 に答える 2

16

あなたのコードはスレッドセーフではありません。複数のスレッドで実行される可能性のある複数のリクエスト間で静的変数を共有しています。基になるストレージとして使用しているクラスはスレッド セーフなクラスではないことに注意してください。つまり、複数のスレッドからメソッドを同時にDictionary<TKey, TValue>呼び出そうとすると、コードがひどくクラッシュする可能性があります。OnAppInit一方、このOnAppInit静的メソッドを Application_Start イベント内で 1 回だけ呼び出している場合 (単一のスレッドから 1 回だけ実行されることが保証されています)、そこで使用しても安全です。

静的変数と静的メソッドは一般的にアプリケーションでは悪い考えであると言われていますが、これは真実ではありません。それらを適切に使用する方法がわからない場合、または並行スレッドからこれを行う必要がある場合にそれらへのアクセスを同期する方法がわからない場合、それらは悪い考えです。スレッド セーフなコードを記述することは非常に難しいテーマであり、間違いを犯す恐れがある場合 (ASP.NET アプリケーションなどのマルチスレッド アプリケーションを記述する場合、誰がそうしないでしょうか?)、単純にこのような状態を共有しないでください。これには、ASP.NET アプリケーションで十分に確立された場所を使用します。

  • バックエンド (リレーショナル データベースなど)
  • アプリケーションの状態
  • キャッシュ
  • HTTP コンテキスト状態
  • セッション状態
  • クライアントのクッキー

これらの場所は、ASP.NET アプリケーションで状態を格納するために特別に設計されています (もちろん、あらゆる種類のアプリケーションで使用できる最初の場所を除きます)。

于 2013-01-08T22:29:46.743 に答える
3

静的変数はリクエスト間で共有されます。さらに、アプリケーションの起動時に初期化されるため、AppDomain、つまりアプリケーションが再起動されると、それらの値が再初期化されます。

于 2013-01-08T22:28:55.743 に答える