0

私はスレッドプーリングのかなりの数の例を読んで見ましたが、必要な方法でそれを理解できないようです。私がなんとかしてうまくいったものは、私が本当に必要としているものではありません。独自のスレッドで関数を実行するだけです。

public static void Main()
    {
        while (true)
        {
            try
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(Process));
                Console.WriteLine("ID has been queued for fetching");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }
            Console.ReadLine();
        }
    }

public static void Process(object state)
{

    var s = StatsFecther("byId", "0"); //returns all player stats
    Console.WriteLine("Account: " + s.nickname);
    Console.WriteLine("ID: " + s.account_id);
    Console.ReadLine();
}

私がやろうとしているのは、プレイヤーの統計を含むシリアル化されたphpデータを取得する約50のスレッド(おそらくそれ以上)を実行することです。ユーザー 0 から始まり、指定したユーザー ID (300,000) まで。私の質問は、統計を取得する方法ではなく、統計を取得して読み取る方法を知っていますが、他のスレッドのつま先を踏まずに 300,000 番目のユーザー ID に達するまで統計を取得し続けるスレッドプールを作成する方法と、統計を取得してデータベースに保存します。

4

2 に答える 2

3
static int _globalId = 0;
public static void Process(object state)
{    
  // each queued Process call gets its own player ID to fetch
  processId = InterlockedIncrement(ref _globalId); 
  var s = StatsFecther("byId", processId); //returns all player stats 

  Console.WriteLine("Account: " + s.nickname);    
  Console.WriteLine("ID: " + s.account_id);    
  Console.ReadLine();
}

これは最も簡単な方法です。しかし、最適とはほど遠いです。同期呼び出しを使用している、呼び出しレートを調整するために ThreadPool に依存している、失敗した呼び出しの再試行ポリシーがなく、アプリケーションはエラー状態 (Web 呼び出しが失敗したとき) で非常に悪い動作をします。

最初に、WebRequest の非同期メソッドの使用を検討する必要があります: BeginGetRequestStream (POST でリクエスト本文がある場合) および/またはBeginGetResponse。これらのメソッドはより適切にスケーリングされ、より少ない CPU でより高いスループットが得られます (もちろんバックエンドが追いつくことができる場合)。

次に、自己抑制を検討する必要があります。同様のプロジェクトで、保留中のリクエスト数を使用しました。成功すると、各呼び出しはさらに 2 つの呼び出しを送信し、スロットリング カウントが上限になります。失敗すると、呼び出しは何も送信しません。保留中のコールがない場合、タイマー ベースの再試行により、1 分ごとに新しいコールが送信されます。このようにして、サービスがダウンしているときに 1 分間に 1 回だけ試行することで、独自のリソースがトラクションなしでスピンするのを防ぎ、サービスがアップしているときにスループットをスロットリング キャップまで上げます。

また、.Net フレームワークは、任意のリソースに対して行う同時接続の数を制限することも知っておく必要があります。宛先のServicePointを見つけて、 ConnectionLimitをその既定値 (2) から調整する最大値に変更する必要があります。

データベースの更新部分については、多くの変数が関係しており、意味のあるアドバイスを提供するには情報が少なすぎます。いくつかの一般的なアドバイスは、データベース呼び出しでも非同期メソッドを使用することです。接続プールのサイズを調整してスロットリング キャップを許可し、更新でプレーヤー ID をキーとして使用して、異なるスレッドから同じレコードを更新する際にデッドロックしないようにしてください。 .

于 2009-09-10T01:24:36.240 に答える
0

ユーザー ID はどのように決定しますか? 1 つのオプションは、スレッド X が 0 から N までの ID を処理するように、すべてのスレッドをセグメント化することです。

于 2009-09-10T00:38:19.203 に答える