Search code examples
c#asynchronousclientinfinite-loopblocking

How can you asynchronously call a method containing an infinite loop without blocking?


I've been working on a client application that connects to a server asynchronously using the async and await keywords. I am trying to asynchronously call a method with an infinite loop that checks for an internet connection every few seconds. Here is the initial code for when I start the connection.

    private async void button1_Click(object sender, EventArgs e)
    {
        if (button1.Text == "Connect")
        {
            button1.Enabled = false;
            await ConnectClient();

            await Task.Run(() => CheckForInternet());
            //Doesn't execute past this line
            button1.Enabled = true;
        }

        ...
    }

Here is the what my CheckForInternet() method does

    private async Task CheckForInternet()
    {      
        while (true)
        {   //Close out of the method when done checking
            if (stopCheckingForInternet)
                return;

            //If there is internet
            if (InternetGetConnectedState())
            {
              ...
            }
            //If an internet connection was lost
            else
            {
              ...
            }
        }

    }

I want the CheckForInternet() method to have its own individual thread after I call it with the ability to not block, but without the need to use the Thread class. I tried out the method used at http://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html

In other words, is there a way to start a thread using these methods asynchronously and then after the thread starts, can control be returned back to the context in which it was called?

The asynchronous call blocks and it will not get past it unless it is completely terminated. I want to have the thread stay running indefinitely but also be able to return to the lines below the one where I call this asynchronous method instead of blocking and never allowing the lines below the call to be executed.


Solution

  • You shouldn't use async/await in this scenario. "await" will make your method block. You should use just a Task.StartNew() for your CheckForInternet method (or other suitable way of creating a Task).

    Inside CheckForInternet I think it's a good idea to put a "Thread.Sleep()" inside it, to avoid unnecessary CPU consumption.

    Creating a Task automatically creates an internal thread.

    Async/await makes much for sense if used for unblocking I/O.