Detilium
Detilium

Reputation: 3026

Using EWS BeginSubscribeToStreamingNotifications

After getting the synchronous streaming notifications to work, I discovered the asynchronous BeginSubscribeToStreamingNotifications().

After fiddling a bit with this, using the very limited documentation there is, I've given up. I simply cannot get this to work.

Environment
here's some of the relevant code. I'm initiating my service, connecting, and calling the BeginSubscribeToStreamingNotifications() method.

public static void InitSubscriptions()
{
    var service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);

    service.Credentials = new NetworkCredential("some", "login", "here");
    service.Url = new Uri("https://some.exchange/server");
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "[email protected]");

    // Initiating the subscription
    var subscription = service.BeginSubscribeToStreamingNotifications(new AsyncCallback(Callback), null, new FolderId[] { WellKnownFolderName.Inbox }, EventType.NewMail);
}

private static void Callback(IAsyncResult result)
{
    // ???
}

As you can see, I have no idea what to do in the callback method.

Problem
I'm not sure how to actually subscribe to notifications using this method. I made it work synchronously, but if possible, I'd like to make it work asynchronously

Here's the synchronous example that works as intended.

public static void InitSubscriptions()
{
    var service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);

    service.Credentials = new NetworkCredential("some", "login", "here");
    service.Url = new Uri("https://some.exchange/server");
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "[email protected]");

    // Initiating the subscription
    var subscription = service.SubscribeToStreamingNotifications(new FolderId[] { WellKnownFolderName.Inbox }, EventType.NewMail);
    var connection = new StreamingSubscriptionConnection(service, 30);

    connection.AddSubscription(subscription);

    // Delegate handlers
    connection.OnNotificationEvent += new StreamingSubscriptionConnection.NotificationEventDelegate(SomeMethod);
    connection.OnSubscriptionError += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(SomeErrorMethod);
    connection.OnDisconnect += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(SomeDisconnectMethod);
}

So my question is: how do I convert the synchronously streaming subscription, into the asynchronously streaming subscription?

Upvotes: 2

Views: 1037

Answers (1)

Jakob Christensen
Jakob Christensen

Reputation: 14956

In the callback you need to call EndSubscribeToStreamingNotifications and then set up the connection and events.

public static void InitSubscriptions()
{
    var service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
    // ...
    service.BeginSubscribeToStreamingNotifications(
        new AsyncCallback(Callback), 
        service, // Pass the service as state.
        new FolderId[] { WellKnownFolderName.Inbox },      
        EventType.NewMail);    
}

private static void Callback(IAsyncResult result)
{
    // Retrieve the service from the passed state.
    var service = result.AsyncState as ExchangeService;
    var subscription = service.EndSubscribeToStreamingNotifications(result);

    var connection = new StreamingSubscriptionConnection(service, 30);
    connection.AddSubscription(subscription);

    // Delegate handlers
    connection.OnNotificationEvent += new StreamingSubscriptionConnection.NotificationEventDelegate(SomeMethod);
    connection.OnSubscriptionError += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(SomeErrorMethod);
    connection.OnDisconnect += new StreamingSubscriptionConnection.SubscriptionErrorDelegate    
}

Note how I pass the service as state to the callback method.

I did not test the code and I never used the Begin/End methods myself but I hope it will get you in the right direction.

If you get it working you may want to have a look at how to convert the Begin/End pattern to a Task based pattern using TaskFactory.FromAsync.

Upvotes: 1

Related Questions