I wrote a method that will start OpenVPN on a config file, and then wait to be connected.It relies on OpenVPN using Local Area Connection 2, which hurts code reusability, but I'm not sure how to do it any other way.private static async void StartOpenVPN(string configFile){    // Start OpenVPN on the config file...    Process.Start(openvpn-gui, $--connect {configFile});    // OpenVPN uses Local Area Connection 2.    var adapter =        NetworkInterface.GetAllNetworkInterfaces()            .First(networkInterface => networkInterface.Name == Local Area Connection 2);    // Wait for Local Area Connection 2 to be operational...    while (adapter.OperationalStatus != OperationalStatus.Up)    {        await Task.Delay(100);        adapter =            NetworkInterface.GetAllNetworkInterfaces()                .First(networkInterface => networkInterface.Name == Local Area Connection 2);    }    Console.WriteLine(Connected!);}Is there a more effective/efficient/elegant way to start OpenVPN on a config file, and then wait to be connected?
Check OpenVPN's connection status
c#;performance;design patterns
Use the Gateway or Unicast IP AddressFor the case of checking if the VPN Connection is online or not, you could consider a solution that just returns a boolean value.Secondly, I wouldn't do it by connection name, instead how about using either the gateway IP address or the unicast IP address?public class OpenVpnConnection{    private IPAddress _gatewayIpAddress;    private IPAddress _unicastIpAddress;    public OpenVpnConnection()    {        _gatewayIpAddress = IPAddress.Parse(10.0.0.1);        _unicastIpAddress = IPAddress.Parse(10.0.0.101);    }    public bool IsNetworkAvailable()    {        if (!NetworkInterface.GetIsNetworkAvailable())            return false;        foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())        {            // discard because of standard reasons            if (ni.OperationalStatus != OperationalStatus.Up) continue;            if (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) continue;            //if (ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel) continue;            // discard if the interface is not virtual            //if (ni.Description.IndexOf(virtual, StringComparison.OrdinalIgnoreCase) <= 0) continue;            //if (ni.Name.IndexOf(virtual, StringComparison.OrdinalIgnoreCase) <= 0) continue;            if (GetIpFromGatewayAddresses(ni).Contains(_gatewayIpAddress)) return true;            if (GetIpFromUnicastAddresses(ni).Contains(_unicastIpAddress)) return true;        }        return false;    }    private static IEnumerable<IPAddress> GetIpFromGatewayAddresses(NetworkInterface nic)    {        return nic.GetIPProperties().GatewayAddresses            .Where(ip => ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)            .Select(ip => ip.Address);    }    private static IEnumerable<IPAddress> GetIpFromUnicastAddresses(NetworkInterface nic)    {        return nic.GetIPProperties().UnicastAddresses            .Where(ip => ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)            .Select(ip => ip.Address);    }}You can take out sections of the code that you don't need, but I included both unicast and gateway options above.You would then simply check if the connection is online byvar vpn = new OpenVpnConnection();bool online = vpn.IsNetworkAvailable();of course, you'll want to pass parameters and what-not, but this is simply to illustrate the idea of moving away from the connection name and using an IP address instead.Putting it togetherA quick and dirty way of piecing it together with you current code would look something like thisprivate static async void StartOpenVPN(string configFile){    // Start OpenVPN on the config file...    Process.Start(openvpn-gui, $--connect {configFile});    var vpn = new OpenVpnConnection(); //of course, send parameters in your actual code    while (!vpn.IsNetworkAvailable)    {        await Task.Delay(100);    }    Console.WriteLine(Connected!);}Rather than using a loop, you could consider using the NetworkChange.NetworkAvailabilityChanged Event instead.