Question

Currently I am connecting my client to the server synchronously.
However, the server is unavailable at times, so I figured using async would be better so I can already gather and format the data I want to send later. I found that the method I am looking for is probably TcpClient.BeginConnect
Unfortunately I am completely new to async operation, so the parameters weird me out.
For one: Is there a specific reason I have to use IP and port seperately, i.e. not use an IPEndPoint?
The more important problem however: AsyncCallback and Object, what are these?
Do I need to change anything on my server?
I think I understood that snyc or asnyc is a local choice and doesn't affect the other side, at least not in compatibility.
Lastly: Here I read about keywords asnyc and await: Where to use them and how?

Here's a little pseudo-code to demonstrate what I have and what I want

private static void send(string msg) {
    TcpClient cli = new TcpClient(localEP);
    bool loop = true;
    while(loop) {      //trying over and over till it works
        try {          //is bad practice and inefficient
            cli.Connect(remoteEP);
        } catch (Exception) {
            ;
        }
        if(cli.Connected)
            break;
    }
    var blah = doOtherThings(msg);
    useTheClient(blah);
}

And now how I wished it to work

private static void send(string msg) {
    TcpClient cli = new TcpClient(localEP);
    cli.BeginConnect(remoteEP); //thread doesn't block here anymore + no exceptions
    var blah = doOtherThings(msg); //this now gets done while cli is connecting
    await(cli.connect == done) //point to wait for connection to be established
    useTheClient(blah);
}
Was it helpful?

Solution

You'll need to create a new AsyncCallback and set it to a specific void where something will be done once the TcpClient is finished connecting to the host. You might also want to check whether the TcpClient connection succeeded or not by checking the value of the TcpClient.Connected

Example

The following example illustrates the asynchronous TcpClient connection to google.com on port 80

static TcpClient cli = new TcpClient(); //Initialize a new TcpClient
static void Main(string[] args)
{
    send("Something");
    Console.ReadLine();
}
private static void doSomething(IAsyncResult result)
{
    if (cli.Connected) //Connected to host, do something
    {
        Console.WriteLine("Connected"); //Write 'Connected'
    }
    else
    {
        //Not connected, do something
    }
    Console.ReadLine(); //Wait for user input
}
private static void send(string msg)
{
    AsyncCallback callBack = new AsyncCallback(doSomething); //Set the callback to the doSomething void
    cli.BeginConnect("google.com", 80, callBack, cli); //Try to connect to Google on port 80
}

Here's a better way to do what you described in the comment

System.Threading.Thread newThread = new System.Threading.Thread((System.Threading.ThreadStart)delegate {
//Do whatever you want in a new thread
    while (!cli.Connected)
    {
        //Do something
    }
});
newThread.Start(); //Start executing the code inside the thread
//This code will still run while the newThread is running
Console.ReadLine(); //Wait for user input
newThread.Abort(); //Stop the thread when the user inserts any thing
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top