J'essaye d'écrire une fonction qui démarre un fil pour chaque "contact", puis interroge (sur le réseau) les résultats de ce contact. Je veux que ma fonction d'attente attende au plus 1,5 seconde pour les réponses, et après cela, il suffit de terminer tous les threads restants. Le problème que je rencontre est que la fonction revient avant que tous les threads soient terminés, même si, selon la logique, cela ne devrait pas être possible. La boucle while dans la fonction principale doit être en attente jusqu'à ce que toutes les discussions ont complètement terminé, mais je reçois la sortie suivante:C# Condition de la race de filetage
FAIL: Storage test 1 exists 0 times in the DHT.
: Storage test 2 exists 0 times in the DHT.
Added storage test 1 to the entries.
Added storage test 2 to the entries.
(Les lignes FAIL proviennent du programme d'essai principal de voir combien de résultats ont été retournés par Get (Selon ce que je peux voir, cela ne devrait pas être possible. Est-ce que quelqu'un sait où l'état de la course pourrait se produire (ou d'autres hypothèses que j'ai faites qui ne sont pas correctes)?
La définition de la fonction est en tant que telle:
public IList<Entry> Get(ID key)
{
ConcurrentBag<Entry> entries = new ConcurrentBag<Entry>();
List<Thread> threads = new List<Thread>();
foreach (Contact c in this.p_Contacts)
{
Thread t = new Thread(delegate()
{
try
{
FetchMessage fm = new FetchMessage(this, c, key);
fm.Send();
int ticks = 0;
// Wait until we receive data, or timeout.
while (!fm.Received && ticks < 1500)
{
Thread.Sleep(100);
ticks += 100;
}
if (fm.Received)
{
foreach (Entry e in fm.Values)
{
Console.WriteLine("Added " + e.Value + " to the entries.");
entries.Add(e);
}
if (entries.Count == 0)
Console.WriteLine("There were no entries to add.");
}
else
Console.WriteLine("The node did not return in time.");
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
);
t.IsBackground = false;
t.Start();
}
while (true)
{
bool stopped = true;
foreach (Thread t in threads)
{
if (t.ThreadState != ThreadState.Stopped)
stopped = false;
}
if (stopped)
break;
Thread.Sleep(100);
}
return new List<Entry>(entries.ToArray());
}
Vous pouvez remplacer le cycle while (true) par un 'foreach (Thread t dans les threads) t.Join()', puis suivez les conseils de Toby en mettant 'threads.Add (t)' avant 't.Start () '[note: mon clavier n'a pas de touche de retour arrière, est-ce que quelqu'un peut corriger mon commentaire?] –