2011-10-19 4 views
1

J'ai une application WinCE C# qui interroge un serveur (JAVA) pour les messages arrivant de manière asynchrone. Ce que je veux réaliser, c'est que je veux interroger le serveur, et quand un résultat est retourné, mettez-le en file d'attente, puis traitez ce résultat dans un autre thread. Je veux isoler le thread de réception asynchrone du thread de processus, car après le traitement de la réponse, je pourrais avoir à faire des POST supplémentaires au serveur.Le processus asynchrone aboutit à un autre thread

Ce que j'ai pour une classe est maintenant similaire à celui présenté ici

http://msdn.microsoft.com/en-us/library/86wf6409%28v=vs.80%29.aspx

pour faire des demandes async au serveur et la lecture de la réponse. J'ai modifié la classe pour inclure un délai d'attente personnalisé, mais cela ne devrait pas avoir d'importance. Ce qui se passe dans mon application, c'est que je commence à interroger dans un thread 'pollingThread', et obtenir la réponse du serveur. En cas d'expiration d'un délai, la réponse sera nulle, sinon j'essaye de traiter la réponse.

Je veux envoyer la chaîne de réponse à un autre thread qui peut travailler sur le traitement, alors que pollingThread revient pour continuer à interroger le serveur. Je ne peux pas comprendre comment obtenir la réponse sur un autre fil. Je sais comment le faire en utilisant Monitor.Pulse sur de grandes fenêtres, mais malheureusement ce n'est pas disponible sur NETCF 3.5.

Des idées?

Merci

EDIT: @ Damon8or

J'ai essayé d'utiliser AutoReset mais pour une raison quelconque, le WaitOne() ne se rend pas compte que l'autre thread a déjà établi() l'événement et il manque le données à venir. Voici ce que j'ai:

Le AutoResetEvent _process est déclarée statique et est visible pour les deux méthodes

ThreadStart processMethod= new ThreadStart(process); 
processingThread= new Thread(processJSONMethod); 
processingThread.IsBackground = true; 
processingThread.Start(); 

ThreadStart startMethod = new ThreadStart(Poll); 
connectionThread = new Thread(startMethod); 
connectionThread.IsBackground = true;      
connectionThread.Start(); 

intérieur du sondage, j'ai _process.Set() recevoir après une chaîne à partir du serveur. Dans la méthode du processus, j'ai:

while (_keepPolling) 
{ 

_process.WaitOne(); 

string text= MyQueue.Dequeue(); 
Debug.WriteLine("Returned: " + text 

}  

Et je ne vois pas la ligne de débogage en cours d'impression. La méthode d'interrogation produit et met en file d'attente la chaîne et retourne à l'interrogation.

+0

Quelle est exactement votre question? –

+0

Je veux m'assurer que je continue d'interroger dans pollingThread pendant que le résultat est traité dans un autre thread. Je ne peux pas comprendre comment réveiller un thread qui fait le traitement du résultat après qu'un résultat est poussé dans la file d'attente – Rishi

Répondre

1

Vous pouvez utiliser AutoResetEvent ou ManualResetEvent pour signaler votre thread de travail. Voici un exemple simple comment.

using System; 
    using System.Linq; 
    using System.Collections.Generic; 
    using System.Text; 
    using System.Threading; 

    namespace QueueDoodles 
    { 
    class Program 
    { 
     public static readonly string[] data = { "a", "b", "c", "d", "e", "f", "g", "h" }; 

     static void Main(string[] args) 
     { 
      var running = true; 
      var rand = new Random(); 
      var q = new Queue<string>(); 
      var qEvent = new ManualResetEvent(false); 
      var pollThread = new Thread(new ThreadStart(delegate() 
      { 
       while (running) 
       { 
        // Queue the next value 
        var value = data[rand.Next(data.Length)]; 
        q.Enqueue(value); 
        Console.WriteLine("{0} queued {1}", Thread.CurrentThread.Name, value); 

        // Signal waiting thread 
        qEvent.Set(); 

        // Simulate polling 
        Thread.Sleep(rand.Next(100)); 
       } 
      })); 
      pollThread.Name = "Poll Thread"; 

      var workerThread = new Thread(new ThreadStart(delegate() 
      { 
       while (running) 
       { 
        // Wait on the queue 
        if (!qEvent.WaitOne()) 
         break; 
        qEvent.Reset(); 

        // Process the next queue item 
        var value = q.Dequeue(); 
        Console.WriteLine("{0} queued {1}", Thread.CurrentThread.Name, value); 
       } 
      })); 
      workerThread.Name = "Worker Thread"; 

      // Start the poll thread 
      pollThread.Start(); 

      // Give it some time to fill queue 
      Thread.Sleep(1000); 

      // Start the worker thread 
      workerThread.Start(); 

      // Wait for keyboard input 
      Console.ReadLine(); 
      running = false; 
      qEvent.Set(); 
     } 
    } 
} 
+0

S'il vous plaît regardez la modification sur la question, je ne pouvais pas tout mettre dans un commentaire.Merci – Rishi

+0

J'ai ajouté un Thread.Sleep (10); juste après le tournage et il semblait avoir aidé WaitOne() à sortir de l'attente. Je ne sais pas quoi faire de cela, mais maintenant j'ai un autre problème où les deux threads ne fonctionnent pas en parallèle. Le thread de traitement semble bloquer le connectionThread, même si ce n'est pas le cas. Juste comme une vérification de santé mentale, j'ai les deux threads comme fils de fond. Cela fait-il une différence? Merci – Rishi

+0

J'ai essayé de passer à AutoResetEvent dans mon code QueueDoodle et cela a fonctionné aussi - commenté l'appel Reset() puisque c'est fait automatiquement avec ce type. Il doit y avoir quelque chose qui se passe avec l'événement ou votre thread de traitement. J'ai beaucoup utilisé ces cours d'événements et ils fonctionnent toujours. Quelques éléments à expérimenter ... -Ajoutez des instructions de débogage dans votre thread de traitement pour voir s'il est en cours d'exécution. -Ajoute un délai au WaitOne (1000) et vérifie le retour juste pour voir si l'événement est en train de se déclencher. -Essayez ManualResetEvent pour voir s'il se comporte différemment. – Damon8or

1

La classe de file d'attente est thread-safe, pourquoi ne pas utiliser une file d'attente pour mettre en file d'attente vos données?

http://msdn.microsoft.com/en-us/library/system.collections.queue.aspx

+0

"Tous les membres d'instance ne sont pas garantis d'être thread-safe." – RandomEngy

+0

En outre, la mise en file d'attente des données n'est pas mon problème. Je peux utiliser des files d'attente pour cela. Mon problème est comment réveiller mon thread 'processeur' pour traiter le résultat tout en m'assurant que mon PolingThread continue à polluer – Rishi

Questions connexes