如何使我的windows桌面c#应用程序重新连接到服务器,以防连接丢失

如何使我的windows桌面c#应用程序重新连接到服务器,以防连接丢失,c#,winforms,signalr,signalr.client,C#,Winforms,Signalr,Signalr.client,我正在开发一个包含服务器端intranet应用程序的通知系统,该应用程序使用Signal将通知发送到客户端,在我的例子中,客户端是windows桌面c#应用程序 顺便说一下,这两个应用程序都是使用Signal和.Net framework 4.5.2实现的c#应用程序 目前,我让我的应用程序连接到服务器以接收通知,我在windows桌面应用程序的启动中实现了这一点 我的问题是,我希望我的应用程序(Windows桌面应用程序)尝试连接到服务器,以防在桌面应用程序已在运行时由于任何原因丢失连接 实现

我正在开发一个包含服务器端intranet应用程序的通知系统,该应用程序使用Signal将通知发送到客户端,在我的例子中,客户端是windows桌面c#应用程序

顺便说一下,这两个应用程序都是使用Signal和.Net framework 4.5.2实现的c#应用程序

目前,我让我的应用程序连接到服务器以接收通知,我在windows桌面应用程序的启动中实现了这一点

我的问题是,我希望我的应用程序(Windows桌面应用程序)尝试连接到服务器,以防在桌面应用程序已在运行时由于任何原因丢失连接

实现这一目标的最佳方式是什么

下面是将我的应用程序连接到intranet应用程序的c#代码

public static HubConnection connection;
static void Main()
{
    IHubProxy _hub;
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);


    string urlToConnectIntoIntranetServer = @"http://localhost:46412";
    connection = new HubConnection(url);
    connection.Headers.Add("Securitytoken", "87654321");
    _hub = connection.CreateHubProxy("NotificationHub");
    _hub.On("broadcastMessage", x => reateToastNotification.CreateToast(x));

    connection.Closed += connection_Closed;
    connection.Start().Wait();
    Application.Run(new Form1());
    CreateToastNotification.CreateToast("Hellow world");
}

  static void connection_Closed()
        {
            Pooling(10);
        }
  private static void Pooling(int i)
        {
            int nTimes = i;
            if (nTimes == 0)
                return;

            try
            {
                if (connection!=null)
                 connection.Start().Wait(); 

            }
            catch (AggregateException ae)
            {
                Thread.Sleep(1000);
                Pooling(nTimes - 1);
            }  
        }

你可以试试这样(这只是一个想法,可能有点难看^^):

private void Connection\u StateChanged(StateChange obj)
{
//当连接断开时
if(obj.NewState==ConnectionState.Disconnected)
{
var current=DateTime.Now.TimeOfDay;
//30秒后启动计时器,每15秒重试一次
设置计时器(当前添加时间跨度从秒数(30)),时间跨度从秒数(15),开始控制);
}否则{
如果(_timer!=null)
_timer.Dispose();
}
}
专用异步任务StartCon()
{
等待连接。开始();
}
私人定时器;
私有void SetTimer(TimeSpan starTime、TimeSpan every、Func action)
{
var current=DateTime.Now;
var timeToGo=开始时间-当前时间的日期;
if(timeToGo
{
action.Invoke();
},null,timeToGo,every);
}

您可以尝试类似的方法(这只是一个想法,可能有点难看^^):

private void Connection\u StateChanged(StateChange obj)
{
//当连接断开时
if(obj.NewState==ConnectionState.Disconnected)
{
var current=DateTime.Now.TimeOfDay;
//30秒后启动计时器,每15秒重试一次
设置计时器(当前添加时间跨度从秒数(30)),时间跨度从秒数(15),开始控制);
}否则{
如果(_timer!=null)
_timer.Dispose();
}
}
专用异步任务StartCon()
{
等待连接。开始();
}
私人定时器;
私有void SetTimer(TimeSpan starTime、TimeSpan every、Func action)
{
var current=DateTime.Now;
var timeToGo=开始时间-当前时间的日期;
if(timeToGo
{
action.Invoke();
},null,timeToGo,every);
}

捕获连接关闭的事件。当它关闭并且要重新连接时,请在处理程序中执行此操作。当它因为您退出应用程序而关闭时,让它关闭。另一方面,您在格式化代码时遇到了一些问题,如果能够解决这些问题以使其更易于阅读,那将是一件好事。谢谢Ben,我想知道您有什么建议可以使代码更易于阅读,所以您的意思是将关闭的事件处理为我的代码段中存在的事件。您可以
connection.Closed+=连接\u Closed已经存在。我们可以看到
连接\u Closed
的定义吗?这将是进行自定义处理的好地方,是吗?捕获连接关闭的事件。当它关闭并且要重新连接时,请在处理程序中执行此操作。当它因为您退出应用程序而关闭时,让它关闭。另一方面,您在格式化代码时遇到了一些问题,如果能够解决这些问题以使其更易于阅读,那将是一件好事。谢谢Ben,我想知道您有什么建议可以使代码更易于阅读,所以您的意思是将关闭的事件处理为我的代码段中存在的事件。您可以
connection.Closed+=连接\u Closed已经存在。我们可以看到
连接\u Closed
的定义吗?那将是一个海关处理的好地方,是吗?
        private void Connection_StateChanged(StateChange obj)
        {
            //when the connection is Disconnected
            if (obj.NewState == ConnectionState.Disconnected)
            {
                var current = DateTime.Now.TimeOfDay;
                // start a timer after 30 secs and retry every 15secs
                SetTimer(current.Add(TimeSpan.FromSeconds(30)), TimeSpan.FromSeconds(15), StartCon);
            } else {
                if(_timer!=null)
                   _timer.Dispose();
            }
        }

        private async Task StartCon()
        {
            await Connection.Start();
        }

        private Timer _timer ;
        private void SetTimer(TimeSpan starTime, TimeSpan every, Func<Task> action)
        {
            var current = DateTime.Now;
            var timeToGo = starTime - current.TimeOfDay;
            if (timeToGo < TimeSpan.Zero)
            {
                return;
            }
            _timer = new Timer(x =>
            {
                action.Invoke();
            }, null, timeToGo, every);
        }