C# 增加EWS流式订阅连接的生存期元素

C# 增加EWS流式订阅连接的生存期元素,c#,exchangewebservices,C#,Exchangewebservices,使用微软的EWS,我们能够监听邮箱并在收到新邮件时采取行动。但是,我不知道如何避免连接超时 根据Microsoft,以下是StreamingSubscriptionConnection的构造函数: public StreamingSubscriptionConnection ( ExchangeService service, int lifetime ) 在我的应用程序中,我将其编码如下: service = new ExchangeService(ExchangeVersi

使用微软的EWS,我们能够监听邮箱并在收到新邮件时采取行动。但是,我不知道如何避免连接超时

根据Microsoft,以下是StreamingSubscriptionConnection的构造函数:

public StreamingSubscriptionConnection (
    ExchangeService service,
    int lifetime
)
在我的应用程序中,我将其编码如下:

service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
StreamingSubscriptionConnection conn = new StreamingSubscriptionConnection(service, 30);

换句话说,我将超时(生存时间)设置为30分钟,因为这是我能设置的最高值。我怎样才能增加这个?或者,即使收到的电子邮件之间间隔约45分钟,我如何欺骗此订阅使其保持活力?

30分钟是一个硬限制。不能将其更改为更高的值


要解决此问题,请将处理程序连接到连接实例的OnDisconnect事件的OnDisconnected处理程序。从那里重新启动订阅(只需从该处理程序调用connection.Open()。

如果有人感兴趣,下面是添加的一点逻辑

我在开始方法中添加了以下内容:

conn.OnDisconnect += 
    new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnDisconnect);
然后,我添加了OnDisconnect方法:

private void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
{
    Start();
}

最终,这仍然需要改进,因为这只是超时并每半小时重新连接一次,而不管传入的电子邮件活动如何。我更希望在每次收到新消息时都能让计数器复位。然后,它每天只会超时几次,而不是48次!尽管如此,这仍然是为了让我的电子邮件监听程序保持在线。

如果其他人感兴趣,我就是这样做到的

我想保持连接打开,所以我在OnDisconnect处理程序中重置它

但是,在重置它之前,我使用反射检查连接对象上的私有“订阅”字典

这允许我在代码的其他地方取消订阅我的连接(OnNotificationEvent),当所有订阅都取消订阅后,我就可以关闭连接

这是我的密码:

 void connection_OnDisconnect(object sender, SubscriptionErrorEventArgs args)
    {
        var c = (Dictionary<string, StreamingSubscription>)typeof(StreamingSubscriptionConnection).GetField("subscriptions",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(sender);

        if (c.Count > 0)
        {
            // reopen the connection
            ((StreamingSubscriptionConnection)sender).Open();

            using (var db = new Metrics_DatabaseEntities())
            {
                PushNotificationTest pt = new PushNotificationTest();
                pt.RetObj = "Connection reset";

                db.PushNotificationTests.Add(pt);

                db.SaveChanges();

            }
        }
        else
        {
            using (var db = new Metrics_DatabaseEntities())
            {
                PushNotificationTest pt = new PushNotificationTest();
                pt.RetObj = "Connection closed!";

                db.PushNotificationTests.Add(pt);

                db.SaveChanges();

            }
        }
    }
void connection\u OnDisconnect(对象发送方、SubscriptionErrorEventArgs args args)
{
var c=(Dictionary)typeof(StreamingSubscriptionConnection).GetField(“订阅”,System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(发送方);
如果(c.计数>0)
{
//重新打开连接
((StreamingSubscriptionConnection)发送方).Open();
使用(var db=new Metrics\u DatabaseEntities())
{
PushNotificationTest pt=新的PushNotificationTest();
pt.RetObj=“连接重置”;
db.PushNotificationTests.Add(pt);
db.SaveChanges();
}
}
其他的
{
使用(var db=new Metrics\u DatabaseEntities())
{
PushNotificationTest pt=新的PushNotificationTest();
pt.RetObj=“连接已关闭!”;
db.PushNotificationTests.Add(pt);
db.SaveChanges();
}
}
}

请忽略这篇文章糟糕的写作方式,这只是我的第一个版本,因为我计划很快写得更干净。我只是想与可能感兴趣的人分享我的方法。

但是,当这是一种合法的分离时呢?例如,有人停止了服务。。。我需要区分这两种情况。啊,我现在明白了。“停止”被视为不同于断开连接。我要了。“谢谢,让我测试一下,赏金就归你了,@Henning Krause。如果一封新邮件刚好在断开连接通知和重新连接呼叫之间到达,会发生什么情况?”?我会错过那封邮件的通知吗?谢谢重新建立连接后,您可以手动执行SyncFolderItems请求,以获取在此时间段内发生的任何错过的事件。OnStart方法是否不需要字符串[]args作为参数?您没有显示Start()方法的内容,但您所做的让我感觉不好。我担心您每天都在创建48个StreamingSubscriptionConnection对象,并且它们不能被垃圾收集,因为它们有一个链接到它们的事件处理程序方法。所以你可能有内存泄漏。一个非常小的,在更大的计划中,但仍然。。。