4

サードパーティのフィードからデータを読み取り、少し変更して保存し、クライアントに返す Web サービスに取り組んでいます。サードパーティのサイトから定期的に更新するだけで済みます。これは、Azure の Web ロールで WCF サービスとして実行されます。

最初は、常に parsefeed メソッドを呼び出すだけだと思っていましたが、最後の更新が早す​​ぎる場合は、その呼び出しを返すようにします...

   public void ParseFeed()
    {
        if (DateTime.Now > lastrun.AddMinutes(1))
        {
         //Fetch updated data into something shared here.
         //thedata is a public static in Global class 
         thedata = fetchdata();
         lastrun=DateTime.Now;            
        }
    }

しかし、フェッチには1〜2秒かかる可能性があるため(Webサービス)、複数のユーザーが一度にそのコードにアクセスすると思います。

from http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607 アプリケーション クラスを含むすべてのクラスの静的メンバーはスレッド セーフではないため、ユーザー コードは適切なロックを提供する必要があります。静的メンバーへのアクセス。これは、アプリケーション クラスに追加するすべての静的メンバーに適用されます。

  • ロックを使用できます(方法がわからない)編集:ここにたくさんの情報があります

  • 静的変数を回避してキャッシュを使用し、そこにデータを入れることができました (ただし、有効期限が切れると削除され、複数のユーザーがデータをフェッチしようとします)。

  • 偽のデータ項目を含むキャッシュを (基本的にはタイマーとして) 使用し、有効期限が切れたときに更新できますが、誰もサイトにアクセスしていなくても更新されます。(スレッドセーフでない場合もあります)

  • 出力キャッシュを実際に使用することはできません。これは、クライアントが私が返すデータに対して、おそらく各要求を一意にする方法でクエリを実行するためです。私のサービスは、要求に従って並べ替えとフィルター処理を行います。

ところで、Azure 上の複数のインスタンスでの結果の一貫性については心配していません。それぞれが独自の状態を取得できるため、複数のサーバーで状態を共有する必要はありません。

私は完全に見逃していた簡単な解決策があると感じています。アイデア?

4

2 に答える 2

1

あなたの質問から、それは次のようになります:

  • 1 分以上古いデータを提供することは認められません
  • 更新時間が同期されていないために、2 つのサービス インスタンスが異なるデータを返す場合は許容されます。
  • データが更新されている間、発信者が 1 ~ 2 秒間ブロックすることは許容されます

これらがすべて当てはまると仮定すると、最も簡単な解決策は、静的変数を使用してデータを格納し、lockチェック/リフレッシュ ブロック全体を構成することです。ダブルチェックのロックパターンのような巧妙なことをしようとさえしません。重要な領域で費やされる時間は、Web サービスを操作するオーバーヘッドと比較して取るに足らないものになるため、ロックの競合は単純に問題にはなりません。

于 2010-11-26T11:46:20.783 に答える
1

おそらく書き込みよりもキャッシュからの読み取りの方が多いため、ReaderWriterLockSlimを使用して、データを複数のスレッドで同時に読み取ることができるが書き込みはできないようにします。また、キャッシュされたデータが不変であることを確認して、消費者によって変更されないようにします。

于 2010-11-26T11:23:56.363 に答える