Quel est le meilleur moyen de transmettre des données entre des threads concurrents dans .NET?

StackOverflow https://stackoverflow.com/questions/106979

Question

J'ai deux threads, il faut interroger plusieurs ressources statiques distinctes à la recherche de mises à jour. L'autre doit récupérer les données et les stocker dans la base de données. Comment le fil 1 peut-il dire au fil 2 qu'il y a quelque chose à traiter?

Était-ce utile?

La solution

Si les éléments de données sont indépendants, traitez-les comme des éléments de travail à traiter par un pool de threads. Utilisez le pool de threads et QueueUserWorkItem pour envoyer les données au (x) thread (s). Vous devez obtenir une meilleure évolutivité en utilisant un pool de threads symétriques et en limitant le nombre de synchronisations à effectuer entre le producteur et le (s) consommateur (s).

Par exemple (à partir de MSDN ):

    TaskInfo ti = new TaskInfo("This report displays the number {0}.", 42);

    // Queue the task and data.
    if (ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), ti)) {    
        Console.WriteLine("Main thread does some work, then sleeps.");

        // If you comment out the Sleep, the main thread exits before
        // the ThreadPool task has a chance to run.  ThreadPool uses 
        // background threads, which do not keep the application 
        // running.  (This is a simple example of a race condition.)
        Thread.Sleep(1000);

        Console.WriteLine("Main thread exits.");
    }
    else {
        Console.WriteLine("Unable to queue ThreadPool request."); 
    }


// The thread procedure performs the independent task, in this case
// formatting and printing a very simple report.
//
static void ThreadProc(Object stateInfo) {
    TaskInfo ti = (TaskInfo) stateInfo;
    Console.WriteLine(ti.Boilerplate, ti.Value); 
}

Autres conseils

J'utilise Monitor.Wait / Pulse sur une file d'attente d'éléments de travail.

Le " magasin dans la base de données " le fil doit toujours être en cours d'exécution? Il semble que la meilleure option (si possible) serait de faire en sorte que le thread d'interrogation fasse tourner un autre thread pour effectuer la sauvegarde. En fonction du nombre de threads créés, il se peut que l'utilisation du premier thread d'interrogation ThreadPool.QueueUserWorkItem () puisse être la route la plus efficace.

Pour plus d'efficacité, lors de l'enregistrement dans la base de données, j'utiliserais des E / S asynchrones sur la base de données plutôt que les méthodes de synchronisation.

Vous devriez éviter de communiquer directement entre deux threads. Si vous devez combiner des primitives de synchronisation, votre code ne sera pas aussi facile à déboguer et pourrait introduire des conditions de course très subtiles qui entraînent une "exécution sur un million". taper des bugs (qui sont loin d’être amusants à trouver / corriger).

Si le deuxième fil doit toujours être exécuté, dites-nous pourquoi avec plus d'informations et nous pourrons revenir avec une réponse plus détaillée.

Bonne chance!

Personnellement, je voudrais que le fil 1 déclenche des événements auxquels le fil 2 peut répondre. Les threads peuvent être connectés aux événements appropriés par le processus de contrôle qui initie les deux threads.

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