简体   繁体   中英

WinForms - System.Reflection.TargetInvocationException in mscorlib.dll when no internet connection is available on application start

I've made a simple desktop application (Winform, in Visual Studio 2015, .NET version 4.5.2) which listens for incoming pusher.com notifications, and does various things depending on what the notification contains. However, there are some issues regarding the internet connectivity - if there is no connection on startup, the application crashes, because of an unhandled exception:

An unhandled exception of type System.Reflection.TargetInvocationException occurred in in mscorlib.dll

The InnerException is No such host is known , and it's understandable, since there's no internet connection.

The StartPushing() bit of the code will continue trying to reconnect if the connection is interrupted while the app is running, and unstable connection is not (the biggest) problem. It's not having the connection before the application is run.

I've also removed StartPushing() from public Form1()1 and placed it within Form1_Shown(...) (thinking that maybe it was called before everything had been setup), but that did not solve the problem - the application kept crashing on startup.

This is my code.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows.Forms;
using Newtonsoft.Json;
using PusherClient;


namespace PusherWebApps
{
    public partial class Form1 : Form
    {
        private static Pusher _pusher;
        public string channel, key;
        public string event1, event2;
        public string iniName = "PusherWebApps.ini";
        public string type;
        WebClient client = new WebClient();

        public Form1()
        {
            InitializeComponent();
            // https://stackoverflow.com/a/39308022
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
            StartPushing();
        }

        void _pusher_ConnectionStateChanged(object sender, PusherClient.ConnectionState state)
        {
            fileLogging("Connection state: " + state.ToString());
        }

        void _pusher_Error(object sender, PusherException error)
        {
            fileLogging("Pusher Channels Error: " + error.ToString());
        }

        // Start
        public async void StartPushing()
        {
            iniParams();
            _pusher = new Pusher(key);
            _pusher.ConnectionStateChanged += _pusher_ConnectionStateChanged;
            _pusher.Error += _pusher_Error;
            PusherClient.ConnectionState connectionState = await _pusher.ConnectAsync();

            Channel _myChannel = await _pusher.SubscribeAsync(channel);

            _myChannel.Bind("myevent", (dynamic incoming) =>
            {
                fileLogging(incoming.ToString());

                dynamic tmp = JsonConvert.DeserializeObject(incoming.ToString());
                dynamic data = JsonConvert.DeserializeObject(tmp.data.ToString());
                dynamic message = JsonConvert.DeserializeObject(data.message.ToString());
                dynamic header = JsonConvert.DeserializeObject(message.header.ToString());

                type = header.type.ToString();

                if (type.ToLower() == event1)
                {
                    // do stuff
                }

                if (type.ToLower() == event2)
                {
                    // do stuff 2
                }
            });
        }

        void _myChannel_Subscribed(object sender)
        {
            fileLogging("Subscribed!");
        }

        public void iniParams()
        {
            bool checkIni = File.Exists(Application.StartupPath + "\\" + iniName);

            if(!checkIni)
            {
                fileLogging("INI missing!");
                MessageBox.Show("INI missing!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }

            var MyIniFile = new IniFile(Application.StartupPath + "\\" + iniName);

            channel = MyIniFile.Read("channel", "Main").ToString();
            key = MyIniFile.Read("key", "Main").ToString();
            event1 = MyIniFile.Read("event1", "Main").ToString();
            event2 = MyIniFile.Read("event2", "Main").ToString();
        }

/************ BEGIN logging **********/
        public void fileLogging(string text)
        {
            // do logging stuff
        }
/********** END logging *********/
    }
}

Finally, my question.

How can I handle this error?

I know that I could probably inform the user that there's no internet connection at startup, and then exit the application, but I'd like to keep it running, and let it keep trying to connect in the background. I would also like to avoid having to use a separate thread and a timer to check for internet connectivity in the background.

EDIT 1

This is the part to which the debugger points - instead of pointing somewhere inside Form1.cs , it highlights this part of Program.cs

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1()); // <== this is the one which the debugger highlights as the error
    }
}

Just add a try/catch to your code. If the app has a GUI or something like that and you want the final user to be able to see it even if it has no internet, you can add the try/catch just to the WebClient part instead of the whole code.

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