Search code examples
c#asynchronousconnectiontasktcpclient

C# - TcpClient asynchronous connection with specific time duration


I am trying to create a function that try to asynchronously connect to a host during a specific time and then check if the connection have been made.

My problem is that I am not able to add a duration for this asynchronous connection.

My function:

 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;
        }
}

I have this error:

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

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

I have searched everywhere and didn't have found a solution.

Thanks for the help

Daniel

WORKING SOLUTION :

 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;
        }
}

Solution

  • Add another delay task, then use Task.WhenAny which return first completed task.
    By comparing completed task with client task you will "decide" which task completed first

    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;
        }
    }
    

    Notice that ConnectAsync method returns Task not Task<bool>.

    Asynchronous method returns value of type Task. Task contain information about the status of asynchronous method (completes, running, faulted etc.)

    And by "awaiting" you will wait and obeserve result of the Task(comleted or faulted with exception)

    So basically

    // start connecting to host
    var clientTask = client.ConnectAsync(ipAddress, port);
    
    // start calculating elapsed time
    var delayTask = Task.Delay(2000);
    

    And await Task.WhenAny will return first task which completes first or throw exception if first task is faulted with exception.