C# EWS exchange有时不使用StreamingSubscription触发NewMail事件

C# EWS exchange有时不使用StreamingSubscription触发NewMail事件,c#,.net,exchangewebservices,C#,.net,Exchangewebservices,我有一个通知新邮件的应用程序,它是使用EWS管理的api(v2.2)创建的。我正在使用StreamingSubscription侦听邮箱事件。我注意到,有时不会触发NewMail事件(我稍后会在邮箱中看到未处理的邮件),不会引发连接/订阅异常,并且在一段时间后,新邮件会接收,因为什么都没有发生。。。是什么导致了这种行为?exchange日志中没有可疑内容,事件只是没有被触发。。。如有任何意见和建议,将不胜感激 谢谢 资料来源: public class ExchangeClient : IDis

我有一个通知新邮件的应用程序,它是使用EWS管理的api(v2.2)创建的。我正在使用StreamingSubscription侦听邮箱事件。我注意到,有时不会触发NewMail事件(我稍后会在邮箱中看到未处理的邮件),不会引发连接/订阅异常,并且在一段时间后,新邮件会接收,因为什么都没有发生。。。是什么导致了这种行为?exchange日志中没有可疑内容,事件只是没有被触发。。。如有任何意见和建议,将不胜感激

谢谢

资料来源:

public class ExchangeClient : IDisposable
{
    private ExchangeService _exchange;
    private SubscriptionBase _subscription;
    private StreamingSubscriptionConnection _connection;

    private bool _disposed;
    private bool _disposing;

    public event EventHandler<ExchangeEventArgs> ExchangeEvent;

    public ExchangeClient(string userName, string password, string domain, ExchangeVersion version)
    {
        _exchange = new ExchangeService(version);
        _exchange.Credentials = new WebCredentials(userName, password);

        _exchange.AutodiscoverUrl(userName + "@" + domain);

        var ids = new FolderId[2] { new FolderId(WellKnownFolderName.Root), new FolderId(WellKnownFolderName.Inbox) };
        var events = new List<EventType>();
        events.Add(EventType.NewMail);

        _subscription = _exchange.SubscribeToStreamingNotifications(ids, events.ToArray());
        _connection = new StreamingSubscriptionConnection(_exchange, 30);
        _connection.AddSubscription((StreamingSubscription)_subscription);
        _connection.OnNotificationEvent += OnNotificationEvent;
        _connection.OnSubscriptionError += OnSubscriptionError;
        _connection.OnDisconnect += OnDisconnect;
        _connection.Open();
    }

    private void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
    {
        if (!_disposing && _connection != null)
        {
            _connection.Open();
        }
    }

    private void OnSubscriptionError(object sender, SubscriptionErrorEventArgs args)
    {
        throw args.Exception;
    }

    private void OnNotificationEvent(object sender, NotificationEventArgs args)
    {
        if (_subscription != null)
        {
            if (args.Subscription.Id == _subscription.Id)
            {
                foreach (var notificationEvent in args.Events)
                {
                    switch (notificationEvent.EventType)
                    {
                        case EventType.Status:
                            break;

                        case EventType.NewMail:
                            NotificationReceived(new ExchangeEventArgs(
                            notificationEvent.EventType,
                            ((ItemEvent)notificationEvent).ItemId, ((ItemEvent)notificationEvent).ParentFolderId));
                            break;

                        default:
                            break;
                    }
                }
            }
        }
    }

    public void Disconnect()
    {
        if (_connection.IsOpen)
            _connection.Close();
    }

    private void NotificationReceived(ExchangeEventArgs e)
    {
        if (ExchangeEvent != null)
        {
            ExchangeEvent(this, e);
        }
    }

    public void Dispose()
    {
        _disposing = true;
        Dispose(_disposing);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing && !_disposed)
        {
            if (_connection != null)
            {
                if (_connection.IsOpen)
                    _connection.Close();
                _connection = null;
            }
            _exchange = null;
            _disposed = true;
        }
    }
}
公共类ExchangeClient:IDisposable
{
私人交换服务交换;
私人订阅库\u订阅;
私有StreamingSubscriptionConnection\u连接;
私人住宅;
私人住宅;
公共事件处理程序ExchangeEvent;
公共ExchangeClient(字符串用户名、字符串密码、字符串域、ExchangeVersion版本)
{
_exchange=新的ExchangeService(版本);
_exchange.Credentials=新的WebCredentials(用户名、密码);
_exchange.AutoDiscoveryURL(用户名+“@”+域);
var id=new FolderId[2]{new FolderId(WellKnownFolderName.Root),new FolderId(WellKnownFolderName.Inbox)};
var events=新列表();
添加(EventType.NewMail);
_订阅=_exchange.SubscribeToStreamingNotifications(id,events.ToArray());
_连接=新的StreamingSubscriptionConnection(_exchange,30);
_连接。添加订阅((StreamingSubscription)\u订阅);
_connection.OnNotificationEvent+=OnNotificationEvent;
_connection.OnSubscriptionError+=OnSubscriptionError;
_connection.OnDisconnect+=OnDisconnect;
_connection.Open();
}
private void OnDisconnect(对象发送方、SubscriptionErrorEventArgs args args)
{
如果(!\u处理和&u连接!=null)
{
_connection.Open();
}
}
SubscriptionError上的私有void(对象发送方、SubscriptionErrorEventArgs args args)
{
抛出args.Exception;
}
私有void OnNotificationEvent(对象发送方、NotificationEventArgs args args)
{
如果(_订阅!=null)
{
if(args.Subscription.Id==\u Subscription.Id)
{
foreach(args.Events中的var notificationEvent)
{
开关(notificationEvent.EventType)
{
案例事件类型。状态:
打破
case EventType.NewMail:
已收到通知(新交换目标)(
notificationEvent.EventType,
((ItemEvent)notificationEvent.ItemId,((ItemEvent)notificationEvent.ParentFolderId));
打破
违约:
打破
}
}
}
}
}
公共空间断开连接()
{
如果(_connection.IsOpen)
_connection.Close();
}
收到私人无效通知(交换目标e)
{
if(ExchangeEvent!=null)
{
交换事件(本,e);
}
}
公共空间处置()
{
_这是真的;
处置;
总干事(本);
}
受保护的虚拟void Dispose(bool disposing)
{
如果(处置和!\u处置)
{
如果(_连接!=null)
{
如果(_connection.IsOpen)
_connection.Close();
_连接=空;
}
_交换=空;
_这是真的;
}
}
}

我想我可以自己回答这个问题-为了保证继续工作,您需要续订。但奇怪的是:没有抛出异常(在
OnDisconnect
事件处理程序的
SubscriptionErrorEventArgs
中有一个异常对象:

无法检索此订阅的事件。必须重新创建订阅

当您不会收到有关订阅事件的通知,并且在一段时间后,您将继续使用旧订阅接收事件通知时超时

更新 我最终得到的解决方案是:如果
OnDisconnect
事件中的
SubscriptionErrorEventArgs
不包含异常-只需打开关闭的连接,否则-引发
Disconnected
事件,让父类决定-我们是否尝试
重新连接
(通过调用
重新连接

公共类ExchangeEventArgs:EventArgs
{
public EventType类型{get;private set;}
public ItemId ItemId{get;private set;}
公共FolderId FolderId{get;private set;}
public ExchangeEventArgs(EventType类型、ItemId ItemId、FolderId FolderId)
{
类型=类型;
ItemId=ItemId;
FolderId=FolderId;
}
}
公共类ExchangeClient:IDisposable
{
私人交换服务交换;
私人订阅库\u订阅;
私有StreamingSubscriptionConnection\u连接;
私人住宅;
私人住宅;
公共事件处理程序ExchangeEvent;
公共事件事件处理程序断开连接;
公共ExchangeClient(字符串用户名、字符串密码、字符串域、ExchangeVersion版本)
{
_exchange=新的ExchangeService(版本);
_exchange.Credentials=新的WebCredentials(用户名、密码);
_exchange.AutoDiscoveryURL(用户名+“@”+域);
_连接=新的StreamingSubscriptionConnection(_exchange,30);
CreateSubscription();
_connection.OnNotificationEvent+=OnNotificationEvent;
_connection.OnSubscriptionError+=OnSubsc
public class ExchangeEventArgs : EventArgs
{
    public EventType Type { get; private set; }
    public ItemId ItemId { get; private set; }
    public FolderId FolderId { get; private set; }

    public ExchangeEventArgs(EventType type, ItemId itemId, FolderId folderId)
    {
        Type = type;
        ItemId = itemId;
        FolderId = folderId;
    }
}

public class ExchangeClient : IDisposable
{
    private ExchangeService _exchange;
    private SubscriptionBase _subscription;
    private StreamingSubscriptionConnection _connection;

    private bool _disposed;
    private bool _disposing;

    public event EventHandler<ExchangeEventArgs> ExchangeEvent;
    public event EventHandler<DisconnectEventArgs> Disconnected;

    public ExchangeClient(string userName, string password, string domain, ExchangeVersion version)
    {
        _exchange = new ExchangeService(version);
        _exchange.Credentials = new WebCredentials(userName, password);
        _exchange.AutodiscoverUrl(userName + "@" + domain);
        _connection = new StreamingSubscriptionConnection(_exchange, 30);

        CreateSubscription();

        _connection.OnNotificationEvent += OnNotificationEvent;
        _connection.OnSubscriptionError += OnSubscriptionError;
        _connection.OnDisconnect += OnDisconnect;
        _connection.Open();
    }

    private void CreateSubscription()
    {
        var ids = new FolderId[2] { new FolderId(WellKnownFolderName.Root), new FolderId(WellKnownFolderName.Inbox) };
        var events = new List<EventType>();
        events.Add(EventType.NewMail);
        if (_subscription != null)
        {
            ((StreamingSubscription)_subscription).Unsubscribe();
            _connection.RemoveSubscription((StreamingSubscription)_subscription);
        }
        _subscription = _exchange.SubscribeToStreamingNotifications(ids, events.ToArray());
        _connection.AddSubscription((StreamingSubscription)_subscription);
    }

    private void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
    {
        if (args.Exception == null)
        {
            if (!_disposing && _connection != null)
            {
                _connection.Open();
            }
        }
        else
        {
            if (Disconnected != null)
                Disconnected(this, new DisconnectEventArgs("Exchange exception", args.Exception));
        }
    }

    public bool Reconnect()
    {
        try
        {
            if (!_disposing && _connection != null)
            {
                CreateSubscription();

                _connection.Open();

                return true;
            }
            else
                return false;
        }
        catch (Exception)
        {
            return false;
        }
    }

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

    private void OnNotificationEvent(object sender, NotificationEventArgs args)
    {
        if (_subscription != null)
        {
            if (args.Subscription.Id == _subscription.Id)
            {
                foreach (var notificationEvent in args.Events)
                {
                    switch (notificationEvent.EventType)
                    {
                        case EventType.Status:
                            break;

                        case EventType.NewMail:
                            NotificationReceived(new ExchangeEventArgs(
                            notificationEvent.EventType,
                            ((ItemEvent)notificationEvent).ItemId, ((ItemEvent)notificationEvent).ParentFolderId));
                            break;

                        default:
                            break;
                    }
                }
            }
        }
    }      

    public void Disconnect()
    {
        if (_connection.IsOpen)
            _connection.Close();
    }

    private void NotificationReceived(ExchangeEventArgs e)
    {
        if (ExchangeEvent != null)
        {
            ExchangeEvent(this, e);
        }
    }

    public void Dispose()
    {
        _disposing = true;
        Dispose(_disposing);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing && !_disposed)
        {
            if (_connection != null)
            {
                if (_connection.IsOpen)
                    _connection.Close();
                _connection = null;
            }
            _exchange = null;
            _disposed = true;
        }
    }
}