Question

J'ai lu et cherché quelques exemples de Threadpooling mais je n'arrive pas à comprendre comment ils le doivent. Ce que j'ai réussi à faire travailler n'est pas vraiment ce dont j'ai besoin. Il exécute simplement la fonction dans son propre thread.

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();
}

Ce que j'essaie de faire, c'est d'avoir environ 50 threads (peut-être plus) qui récupèrent des données php sérialisées contenant des statistiques de joueur. À partir de l'utilisateur 0 jusqu'à l'ID utilisateur spécifié (300 000). Ma question ne concerne pas la manière de récupérer les statistiques. Je sais comment obtenir les statistiques et les lire. enregistre les statistiques car il les récupère dans une base de données.

Était-ce utile?

La solution

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();
}

C’est la chose la plus simple à faire. Mais c'est loin d'être optimal. Vous utilisez des appels synchrones, vous vous fiez au ThreadPool pour contrôler votre taux d'appels, vous n'avez aucune stratégie de nouvelle tentative pour les appels ayant échoué et votre application se comportera de manière extrêmement mauvaise en cas d'erreur (lorsque les appels Web échouent).

D'abord, vous devriez envisager d'utiliser les méthodes asynchrones de WebRequest: BeginGetRequestStream (si vous POST et que vous avez un corps de requête) et / ou BeginGetResponse . Ces méthodes évoluent beaucoup mieux et vous obtiendrez un débit total plus élevé avec moins de CPU (si le back-end peut le suivre bien sûr).

Deuxièmement, vous devriez envisager l'auto-throthling. Sur un projet similaire, j'ai utilisé un nombre de demandes en attente. En cas de succès, chaque appel soumettrait 2 autres appels, plafonnés avec le nombre de throtling. En cas d'échec, l'appel ne soumettrait rien. Si aucun appel n'est en attente, une nouvelle tentative basée sur un minuteur soumet un nouvel appel toutes les minutes. De cette façon, vous ne tentez qu'une fois par minute lorsque le service est en panne, ce qui vous évite de tourner sans traction et que vous augmentez le débit jusqu'à ce que le niveau de service augmente lorsque le service est activé.

Vous devez également savoir que le framework .Net limitera le nombre de connexions concurrentes qu’il effectue avec toutes les ressources. Vous devez trouver votre destination ServicePoint et la modifier. ConnectionLimit à partir de sa valeur par défaut (2 ) à la valeur maximale que vous souhaitez limiter.

En ce qui concerne la partie mise à jour de la base de données, de nombreuses variables sont en jeu et beaucoup trop peu d’informations pour donner des conseils utiles. Un conseil général serait également d’utiliser des méthodes asynchrones dans l’appel de base de données, assurez-vous que vos mises à jour utilisent l’ID du lecteur comme clé pour ne pas bloquer le même enregistrement à partir de threads différents. .

Autres conseils

Comment déterminez-vous l'ID utilisateur? Une option consiste à segmenter tous les threads de manière à ce que le thread X traite les identifiants de 0 à N, et ainsi de suite, sous forme de fraction du nombre de threads que vous avez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top