2017-01-06 4 views
1

J'essaie de créer une fonction qui essaie de se connecter de façon asynchrone à un hôte pendant une durée spécifique, puis de vérifier si la connexion a été établie.C# - Connexion asynchrone TcpClient avec une durée spécifique

Mon problème est que je ne suis pas en mesure d'ajouter une durée pour cette connexion asynchrone.

Ma fonction:

public async Task<bool> IsConnected() 
{ 
     // Host IP Address and communication port 
     string ipAddress = "192.168.0.11"; 
     int port = 9100; 

     //Try to Connect with the host during 2 second 
     { 
      // Create TcpClient and try to connect 
      using (TcpClient client = new TcpClient()) 
      { 
       Task<bool> mytask = client.ConnectAsync(ipAddress, port).Wait(TimeSpan.FromSeconds(2)); 
       bool isconnected = await mytask; 

       if (isconnected) 
       { 
        //Connection with host 
        return true; 
       } 
       else 
       { 
        // No connection with host 
        return false; 
       } 
       //Close Connection 
       client.Close(); 
      } 
     } 
     catch (Exception exception) 
     { 
      // Problem with connection 
      return false; 
     } 
} 

J'ai cette erreur:

Cannot implicitly convert type 'bool' to 'System.Threading.Tasks.Task<bool>' at line : 

Task<bool> mytask = client.ConnectAsync(ipAddress, port).Wait(TimeSpan.FromSeconds(2)); 

J'ai cherché partout et ne pas avoir trouvé une solution.

Merci pour l'aide

Daniel

SOLUTION DE TRAVAIL:

public async Task<bool> IsConnected() 
{ 
     // Host IP Address and communication port 
     string ipAddress = "192.168.0.11"; 
     int port = 9100; 

     //Try to Connect with the host during 2 second 
     { 
      // Create TcpClient and try to connect 
      using (TcpClient client = new TcpClient()) 
      { 
       //Create Tasks 
       var clientTask = client.ConnectAsync(ipAddress, port); 
       var delayTask = Task.Delay(2000); 

       //Check which one finish first 
       var completedTask = await Task.WhenAny(new[] {clientTask, delayTask}); 

       //Check if the connection have been established before the end of the timer 
       return completedTask == clientTask; 
      } 
     } 
     catch (Exception exception) 
     { 
      // Problem with connection 
      return false; 
     } 
} 
+0

Par ex. http://stackoverflow.com/questions/13838088/how-to-define-a-more-aggressive-timeout-for-httpwebrequest –

+1

'client.Close' est redondant parce que vous utilisez déjà' using' et 'client.Dispose() 'quelle connexion étroite sera exécutée de toute façon. En fait 'client.Close()' exécute 'client.Dispose()' – Fabio

+0

Merci fabio :) je vais changer ma solution de travail –

Répondre

5

Ajouter une autre tâche de retard, puis utilisez Task.WhenAny qui reviennent première tâche terminée.
En comparant tâche terminée avec la tâche client vous « décider » quelle tâche terminée la première

public async Task<bool> IsConnected() 
{ 
    using (TcpClient client = new TcpClient()) 
    { 
     var clientTask = client.ConnectAsync(ipAddress, port); 
     var delayTask = Task.Delay(2000); 

     var completedTask = await Task.WhenAny(new[] {clientTask, delayTask}); 
     return completedTask == clientTask; 
    } 
} 

Notez que ConnectAsync méthode retourne Task pas Task<bool>.

La méthode asynchrone renvoie la valeur du type Task. Tâche contient des informations sur l'état de la méthode asynchrone (terminée, en cours d'exécution, etc. faillé)

Et par « attente » vous attendrez et le résultat de obeserve de la tâche (comleted ou en défaut à l'exception)

Donc, fondamentalement

// start connecting to host 
var clientTask = client.ConnectAsync(ipAddress, port); 

// start calculating elapsed time 
var delayTask = Task.Delay(2000); 

Et await Task.WhenAny retournera la première tâche qui termine la première ou lance une exception si la première tâche est défaillante avec exception.

+0

Merci beaucoup c'est une très bonne idée et ça fonctionne parfaitement :) –