1

私は C/C++ のバックグラウンドを持っており、C# でいくつかのことを行うのに問題があります。私の問題はstatic、C++ のように機能するキーワードが必要なことです。プロパティがクラスのすべてのインスタンスに対してグローバルであるように、これは C# の機能です。しかし、私が望んでいないのは、C#(/ASP.NET) での永続性です。現在実行中のページのみのクラスのすべてのインスタンスに対してグローバルな静的プロパティが必要です。

どうすればこれを行うことができますか?

基本的に私がこれを使用しているのは、現在実行中のページでのみ一意でなければならない一意の名前付けです。静的プロパティが永続的である場合、トラフィックが多い期間に整数ロールオーバーが発生する可能性がはるかに高くなり、同じ値が 2 回使用される可能性があります。

誰かがページに行った場合のように

static int i=0;
page_load...{
  lbl.Text=i;
  i++;
}

そして、他の誰かが同じページに行った場合、彼らも0を取得します。しかし、クラスのすべてのインスタンスで同じになるように、静的プロパティも持っています。

4

6 に答える 6

4

残念ながら、この場合、2 つの互換性のない概念を組み合わせようとしているため、必要なものを取得することはできません。

  • static は、インスタンスへのバインドからメンバー (メソッド、プロパティ、フィールドなど) を解放する C# の修飾子です。これは、AppDomain 内の型により正確にバインドされたインスタンスです。
  • 現在実行中のページに固有のカウンターは、必ずインスタンスに関連付けられます

あなたの最善の策は、インスタンス レベルのプロパティを作成し、インスタンスを継承してカウンターを更新するために必要なことを行うことだと思います。

しかし、私はまだあなたのシナリオについて少し不明確です. 次のいずれかが必要なようです...

  • 実行中のページの現在のインスタンスに固有のプロパティ
  • 実行中のページのすべてのインスタンスに固有のプロパティ
  • 現在のセッション内のページのすべての使用に固有のプロパティ

これらのどれが問題なのかを明確にしていただけますか?

于 2009-09-08T15:10:07.523 に答える
3

これを行うための本当にきれいな方法はありませんが、オブジェクトが常に HTTP ページ/リクエストのコンテキストで存在する場合は、現在のItemsコレクションHttpContextを使用できます。

public class YourClass
{
    private static readonly string _itemKey = "Key Goes Here";
    private readonly HttpContext _context;

    public YourClass()
    {
        _context = HttpContext.Current;
        if (_context == null) throw new InvalidOperationException("Boom!");

        // set a default value here if you like...
        if (_context.Items[_itemKey] == null)
        {
            _context.Items[_itemKey] = new YourType("Default Value");
        }
    }

    public YourType NonPersistentStatic
    {
        get { return (YourType)(_context.Items[_itemKey]); }
        set { _context.Items[_itemKey] = value; }
    }
}
于 2009-09-08T15:16:42.697 に答える
1

あなたの質問を100%理解しているかどうかはわかりませんが...

あなたが本当に探しているのは、オブジェクトをセッションに保存することだと思います。

私がすることは、このようなものです

public class PageBase : Page
{

    public MyObject Foo 
    {
        get { return (MyObject)Session["myobject"]; }
        set { Session["myobject"] = value; }
    }
}

そして、PageBase から継承するようにページを変更します

編集: ASP.NET 内での影響を調べた[ThreadStatic]後、Scott Hanselmen によるこのブログ投稿に出くわしました。[ThreadStatic] 属性と System.Web.HttpContext.Current.Items の 2 つの手法の物語。彼はまた、オブジェクトを格納できる組み込みの辞書を持つ HttpContext の存在を指摘しました。私はこれについて完全に忘れていました。

于 2009-09-08T15:11:37.117 に答える
0

なぜそれが必要なのかわかりません。セッションに固有のものを HTTPContext.Current.Session に保存できます。リクエストに固有のものを HTTPContext.Current.ViewState に保存できます。

やりたいことを行うには、スレッドセーフなオブジェクトのアプリケーション スコープ変数を宣言する必要があります。以下の例では、すべてのページで一意の番号が得られます。

1) アプリケーションスコープ変数はデフォルトではスレッドセーフではないため、スレッドセーフなカウンタークラスを作成します

public class ThreadSafeCounter
{
  private object _padlock = new object;
  private int _counterValue = 0;

  public int GetNextValue()
  {
     int temp;
     lock(_padlock)
     {
       _counter++;
       temp = _counter;
     }
     return temp;
  }

}

2) Global.asax Application_Start イベントでアプリケーション変数を作成します。

HttpContext.Current.Application["MyCounter"] = new ThreadSafeCounter();

3) ページのコード ビハインドでこれにアクセスします。

var counter = HttpContext.Current.Application["MyCounter"] as ThreadSafeCounter;
if (counter != null)
{
  var uniqueValue = counter.GetNextValue();
  // DO SOME WORK HERE
}
else
{
  //throw some exception here
}

潜在的な落とし穴: これをサーバー ファーム全体に展開する場合、または複数のワーカー プロセスがある場合は、セッション モードが状態サーバーまたは SQL Server ベースであることを確認してください。InProc の場合は、要求を処理する各サーバー/プロセスだからです。専用のカウンターになります。

于 2009-09-08T20:37:44.233 に答える
0

あなたが求めているのは ThreadStatic 変数ですが、それは良い解決策ではありません。それは機能しますが、それを処理するための堅牢な方法ではありません。たとえば、ThreadStatic 変数は最初のスレッドに対してのみ初期化されるため、各スレッドの初期化を自分で処理する必要があります。

まず、各要素に一意の ID を提供するための組み込み機能を調べる必要があります。たとえば、同じコントロールが繰り返されるようにリピーターがある場合、各反復は、コントロール ID の前に追加される一意の ID を取得します。ClientID プロパティを使用して、この一意の ID を取得できます。

命名を自分で処理する必要がある場合は、Page クラスのメンバー変数を使用して命名を追跡する必要があります。クラスのコンストラクターで変数を簡単に初期化できます。変数はそれ以前には存在しないため、初期化される前に誤って使用することはありません。

于 2009-09-08T15:30:21.173 に答える
0

「静的」はどこから参照していますか?子コントロールだけの場合は、通常のインスタンス プロパティをページ クラスに追加し、子コントロールのページ プロパティを介してその変数を参照します。

public class DefaultPage : Page {
    public string MyProperty { get; set; }
} 

public class DefaultControl : UserControl {
    //...
    ((DefaultPage)this.Page).MyProperty
    //...
}

正直なところ、このコードを見ると、デザインが少し後退していると思います。ページは、必要なすべてのデータをユーザー コントロールに提供する必要があります。

于 2009-09-08T15:09:37.783 に答える