0

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.

Zach
  • 177
  • 2
  • 2
  • 9
  • `Task.Factory.StartNew(() => CheckForInternet())` - I haven't used the new `await` stuff in C#, but I want to say if you don't want to block on the UI thread, then just spin off the new task without awaiting. – Anthony Jul 29 '14 at 20:36
  • Your solution worked! You should have posted it as answer. – Zach Jul 29 '14 at 23:04
  • Oh well, I was in a hurry and didn't read the whole question so I figured I would have missed something. Wanted to comment on my first though in case I never got back to properly answer the question. – Anthony Jul 30 '14 at 01:23

2 Answers2

0

You could choose not to await the task returned by Task.Run; that would make your loop independent.

However, I would recommend that you either have a top-level try/catch within CheckForInternet, or save the returned Task and respond appropriately when it completes.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
0

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.

Eric Lemes
  • 561
  • 3
  • 10