如何在不阻塞的情况下异步调用包含无限循环的方法?

时间:2014-07-29 20:25:16

标签: c# asynchronous client infinite-loop blocking

我一直致力于使用async和await关键字以异步方式连接到服务器的客户端应用程序。我试图异步调用一个无限循环的方法,每隔几秒检查一次互联网连接。这是我开始连接时的初始代码。

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

        ...
    }

这是我的CheckForInternet()方法的作用

    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
            {
              ...
            }
        }

    }

我希望CheckForInternet()方法在我调用它之后拥有自己独立的线程,并且能够不阻塞,但不需要使用Thread类。我尝试了用于的方法 http://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html

换句话说,有没有办法以异步方式使用这些方法启动线程,然后在线程启动后,可以控制返回到调用它的上下文?

异步调用阻止,除非完全终止,否则它不会超过它。我想让线程无限期地运行,但也能够返回到我调用此异步方法而不是阻塞的行下面的行,并且永远不允许执行调用下面的行。

2 个答案:

答案 0 :(得分:0)

您可以选择不await Task.Run返回的任务;这将使你的循环独立。

但是,我建议您在try中拥有顶级catch / CheckForInternet,或者保存返回的Task并在完成时做出相应的回应。

答案 1 :(得分:0)

在这种情况下,您不应该使用async / await。 “await”将使你的方法阻止。您应该只使用Task.StartNew()作为CheckForInternet方法(或其他合适的创建任务的方法)。

CheckForInternet内部我认为在其中放置一个“Thread.Sleep()”是个好主意,以避免不必要的CPU消耗。

创建任务会自动创建内部线程。

如果用于解锁I / O,则异步/等待很有意义。