.NET 在 Exchange Server EWS Managed 中处理事件通知 API

.NET Handling Event Notifications in Exchange Server EWS Managed API

在 EWS 中处理 NotificationEvents 时,以下 MSDN 文档 https://msdn.microsoft.com/en-us/library/office/hh312849(v=exchg.140).aspx 由 Henning Krause 编写。

显示了 2 种不同的方法来解决这个问题,请参阅下面的代码:

EX 1

private static void OnNotificationEvent(object sender, NotificationEventArgs args)
    {
        // Extract the item ids for all NewMail Events in the list.
        var newMails = from e in args.Events.OfType<ItemEvent>()
                       where e.EventType == EventType.NewMail
                       select e.ItemId;

        // Note: For the sake of simplicity, error handling is ommited here. 
        // Just assume everything went fine
        var response = _ExchangeService.BindToItems(newMails,
                                                    new PropertySet(BasePropertySet.IdOnly, ItemSchema.DateTimeReceived,
                                                                    ItemSchema.Subject));
        var items = response.Select(itemResponse => itemResponse.Item);

        foreach (var item in items)
        {
            Console.Out.WriteLine("A new mail has been created. Received on {0}", item.DateTimeReceived);
            Console.Out.WriteLine("Subject: {0}", item.Subject);
        }
    }

    private static void OnSubscriptionError(object sender, SubscriptionErrorEventArgs args)
    {
        // Handle error conditions. 
        var e = args.Exception;
        Console.Out.WriteLine("The following error occured:");
        Console.Out.WriteLine(e.ToString());
        Console.Out.WriteLine();
    }


}

EX 2

private static void OnNotificationEvent(object sender, NotificationEventArgs args){
   foreach (var notification in args.Events){
      if (notification.EventType != EventType.NewMail) continue;
      Console.WriteLine("A new mail has been created");
      var itemEvent = (ItemEvent) notification;
      Console.WriteLine("The item ID of the new mail is {0}", itemEvent.ItemId.UniqueId);
   }
}

使用一种方法优于另一种方法的 differences/advantages 是什么?

该示例仅展示了如何处理 1 个特定的 EventType,但在我的应用程序中,我实际上想知道项目何时获得 1. 更新和 2. 删除。

见下文:

Private Sub OnEvent(sender As System.Object, args As NotificationEventArgs)
    Dim oGuid As New Guid(DefaultExtendedPropertySet.PublicStrings)
    Dim oInternalContactId As New ExtendedPropertyDefinition(oGuid, conContactIdPropertyName, MapiPropertyType.Integer)
    Dim oDateAdded As New ExtendedPropertyDefinition(oGuid, conDteAddedPropertyName, MapiPropertyType.String)
    Dim oDateUpdated As New ExtendedPropertyDefinition(oGuid, conDteUpdatedPropertyName, MapiPropertyType.String)
    Dim lstUpdatedContactIds As New List(Of ItemId)
    Dim lstDeletedContactIds As New List(Of ItemId)
    Dim lstUpdatedContacts As New List(Of Contact)
    Dim lstDeletedContacts As New List(Of Contact)
    Dim oUpdatedContacts As ServiceResponseCollection(Of GetItemResponse)
    Dim oDeletedontacts As ServiceResponseCollection(Of GetItemResponse)
    Dim intInternalContactId As Integer

    lstUpdatedContactIds = From e In args.Events.OfType(Of ItemEvent)()
                           Where e.EventType = EventType.Modified
                           Select e.ItemId

    lstDeletedContactIds = From e In args.Events.OfType(Of ItemEvent)()
                           Where e.EventType = EventType.Deleted
                           Select e.EventType


    If lstUpdatedContactIds.Count > 0 Then
        oUpdatedContacts = args.Subscription.Service.BindToItems(lstUpdatedContactIds, New PropertySet(BasePropertySet.FirstClassProperties, oInternalContactId, oDateAdded, oDateUpdated))
        lstUpdatedContacts = oUpdatedContacts.Where(Function(collection) collection.Item.TryGetProperty(oInternalContactId, intInternalContactId))
    End If

    If lstDeletedContactIds.Count > 0 Then
        oDeletedontacts = args.Subscription.Service.BindToItems(lstDeletedContactIds, New PropertySet(BasePropertySet.FirstClassProperties, oInternalContactId, oDateAdded, oDateUpdated))
        lstDeletedContacts = oDeletedontacts.Where(Function(collection) collection.Item.TryGetProperty(oInternalContactId, intInternalContactId))
    End If

    Next
End Sub 

按照 EX 1 中的方法,我是在正确的轨道上还是按照 EX 2 中的方法更好?

如果每次捕获事件时都会触发 OnNotificationEvent,为什么我们期待事件集合(EX 1)并使用 LINQ,难道我们不应该期待单个事件吗?

Exchange 如何处理来自不同邮箱的多个连续事件通知,它会自动将它们排队直到我们处理它们吗?

请记住,我同时监控着数百个邮箱。

谢谢!

您会发现,在 Exchange 中,这似乎是一个谨慎的操作,例如创建一个新项目,通常会导致许多通知被传递到您的事件处理程序。现在我专门处理日历项目,自动接受的工作流程一直会导致多个事件。对于收件箱中的标准电子邮件项目,我不确定会发生什么,但可能会随着 NewMail 事件发生变化。根据我的经验,每个事件处理程序调用中的多个通知总是针对一个邮箱。

我不太明白 EX1 和 EX2 之间的区别,但我建议您不要在事件处理程序中使用 BindToItems。最好保存 ItemId 和通知类型并在另一个主线线程上处理它们。与任何事件处理程序一样,您希望尽量减少在其中的时间。

HTH