2017-03-03 1 views
0

Comme je ne pouvais pas trouver un moyen de jeter un coup d'oeil pour les données (lire les données sans consommer le tampon) comme demandé au How to peek StreamSocket for data in UWP apps J'essaie maintenant faire mon "coup d'oeil" mais toujours pas de chance.Dans UWP StreamSocket, puis-je lire les données avec timeout et laisser la connexion ouverte si le délai expire

Je ne vois pas comment je peux lire les données de StreamSocket de la manière qui me permettra d'utiliser des délais d'attente et de laisser la connexion utilisable dans le cas où le délai expire.

En fin de compte, le problème est le suivant. Dans mon client IMAP, j'obtiens une réponse d'un serveur et si cette réponse est négative, je dois attendre un peu pour voir si le serveur envoie immédiatement une autre réponse (parfois, le serveur peut le faire, avec des détails supplémentaires) sur l'erreur ou même un paquet zéro pour fermer la connexion). Si le serveur n'a pas envoyé une autre réponse, je vais bien, laissant simplement la méthode et revenant à l'appelant. L'appelant peut alors envoyer plus de données au flux, recevoir plus de réponses, etc.

Donc, après avoir envoyé une requête et obtenu une réponse initiale, j'ai besoin dans certains cas de lire à nouveau le socket avec un très petit intervalle de temps et si non les données arrivent, ne font rien.

Répondre

1

Vous pouvez utiliser un CancelationTokenSource pour générer un délai et arrêter une opération asynchrone. Le DataReader consomme les données du flux d'entrée du StreamSocket. Sa méthode LoadAsync() retournera lorsqu'il y aura au moins un octet de données. Ici, nous ajoutons une source d'annulation qui annulera la tâche asynchrone après 1 seconde pour arrêter DataReader.LoadAsync() si aucune donnée n'a été consommée.

var stream  = new StreamSocket(); 

var inputStream = stream.InputStream; 

var reader  = new DataReader(inputStream); 
reader.InputStreamOptions = InputStreamOptions.Partial; 

while(true) 
{ 
    try 
    { 
     var timeoutSource = new CancellationTokenSource(TimeSpan.FromSeconds(1)); 
     var data = await reader.LoadAsync(1).AsTask(timeoutSource.Token); 

     while(reader.UnconsumedBufferLength > 0) 
     { 
      var read = reader.ReadUInt32(); 
     } 
    } 
    catch(TaskCanceledException) 
    { 
     // timeout 
    } 
} 

N'oubliez pas que la suppression de DataReader ferme le flux et la connexion.

+0

Merci. Mais comment puis-je me débarrasser de DataReader une fois qu'il a fait son travail? Je devrai alors renvoyer la connexion à l'appelant dans le même état qu'avant. Idéalement, je dois pouvoir l'attacher à la connexion existante et la détacher plusieurs fois pendant la durée de vie de la connexion. – Alex

+1

Vous pouvez détacher le flux du lecteur à l'aide de DetachStream(): https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader#Windows_Storage_Streams_DataReader_DetachStream. Cela vous permettra de garder le Stream ouvert lors de la mise au rebut du lecteur. – Vincent

+0

Oups, lors de la vérification sur DataReader, j'ai trouvé que je l'utilisais déjà dans mon autre code exactement dans le même but et il semble que j'ai complètement oublié que j'avais déjà résolu cette tâche il y a quelques mois .. Incroyable .. – Alex