简体   繁体   中英

Check internet asynchronously in C# / ASP.NET

My application needs a few websites to be active to work properly. So, I want to check for websites using ping/webclient but it can take a few seconds to execute. This code can run asynchronously but I want this code to be over before login button is clicked.

My code is:

//CheckWebService method is used to check if all websites are active

public static void CheckWebService()
{
    try
    {
        WebClient WebClient = new WebClient();
        WebClient.OpenRead("https://www.website1.com");
        WebClient.OpenRead("https://www.website2.com");
        WebClient.OpenRead("https://www.website3.com");
        WebClient.OpenRead("https://www.website4.com");
    }
    catch (Exception Ex)
    {
        MessageBox.Show("Internet issues");
    }
}

//This task is made public so that I can start it in Form load event, and can wait for it to compete in my login button click event.

Task CheckWebService;

private void LoginForm_Load(object sender, EventArgs e)
{
    CheckWebService = Task.Run(() =>
        {
            CheckWebService();
        });
}

private void LoginButton_Click(object sender, EventArgs e)
{
    CheckWebService.Wait();

    //Login verification code. CheckWebService method must be complete before login code executes.
}

Am I doing this correctly?

You're using some pretty old tech and creating unnecessary threads. It's much simpler if you make your event handler async, like this:

private async void LoginForm_Load(object sender, EventArgs e)
{
    await CheckWebService();
}

Also, HttpClient is more modern and has async methods:

public async Task CheckWebService()
{
    try
    {
        using (var client = new HttpClient())
        {
            await client.GetAsync("https://www.website1.com");
            await client.GetAsync("https://www.website2.com");
            await client.GetAsync("https://www.website3.com");
            await client.GetAsync("https://www.website4.com");
        }
    }
    catch (HttpRequestException Ex)
    {
        MessageBox.Show("Internet issues");
    } 
}

That's the basic change. In addition, you may want to execute the requests in parallel, to improve response time. Also, you might want to check the response code from the services. Also, you should only catch the specific exceptions your code can handle; if there is a system error (like out of memory) you want that to bubble up.

Here's how you'd do all that:

public async Task CheckWebService()
{
    bool success = false;
    try
    {
        using (var client = new HttpClient())
        {
            var tasks = new[]
            {
                client.GetAsync("http://website1.com"),
                client.GetAsync("http://website2.com"),
                client.GetAsync("http://website3.com"),
                client.GetAsync("http://website4.com"),
            };
            await Task.WhenAll(tasks);
            var results = tasks.Select(t => t.Result).ToList();
            if (results.All(r => r.StatusCode == System.Net.HttpStatusCode.OK))
            {
                success = true;
            }
        }
    }
    catch (HttpRequestException exception)
    {
    }
    if (!success) MessageBox.Show("Error");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM