如何异步调用包含无限循环的方法而不阻塞

本文关键字:方法 无限循环 包含 何异步 异步 调用 | 更新日期: 2023-09-27 18:15:44

我一直在开发一个客户端应用程序,该应用程序使用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

换句话说,是否有一种方法可以使用这些方法异步启动线程,然后在线程启动后,可以将控制返回到调用它的上下文中?

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

如何异步调用包含无限循环的方法而不阻塞

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

Inside CheckForInternet我认为在里面放一个"Thread.Sleep()"是个好主意,以避免不必要的CPU消耗

创建Task会自动创建一个内部线程。

Async/await如果用于解除阻塞I/o,那就更有意义了。

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

但是,我建议您在CheckForInternet中使用顶级try/catch,或者保存返回的Task,并在完成时进行适当的响应。