Question

we use EWS Managed API to Sync our CRM with the Exchange-Server. As long as I used EWS Mangage API 1.1 everything worked perfect. Now I updated to Api 2.0 (Dll-version: 15.0.516.14) and I'm getting an ArgumentException if I bind to the same Folder from diffrent threads and don't understand why.

Here's a samplecode which raises the exception:

private void TestAsyncFolderGet()
    {
        try
        {
            ExchangeService service = this.GetService();

            Parallel.For(0, 20, (i) =>
                {
                    Folder fo = Folder.Bind(service, WellKnownFolderName.Inbox);
               });

        }
        catch (Exception ex)
        {
            this.State = "Failed: " + ex.Message;
        }
    }

    private ExchangeService GetService()
    {
        ExchangeService result = new ExchangeService(ExchangeVersion.Exchange2010);

        result.AutodiscoverUrl("test@foo.com");

        return result;
    }

My real scenario is that im getting changed items using a pullsubscription and handle the changes async. While doing this I'm binding to the parentfolder to get some informations.

Can anyone help me avoid the Exception?

Stacktrace and exception infos:

System.ArgumentException: An item with the same key has already been added.

at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) at Microsoft.Exchange.WebServices.Data.ExchangeServiceBase.SaveHttpResponseHeaders(WebHeaderCollection headers) at Microsoft.Exchange.WebServices.Data.SimpleServiceRequestBase.ReadResponse(IEwsHttpWebResponse response) at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalFindFolders(IEnumerable1 parentFolderIds, SearchFilter searchFilter, FolderView view, ServiceErrorHandling errorHandlingMode) at Microsoft.Exchange.WebServices.Data.ExchangeService.FindFolders(FolderId parentFolderId, FolderView view)

Was it helpful?

Solution

I made a supportcall to Microsoft and got this answer...

I am from the Messaging Developer Support team and have now taken ownership of this case. I’ve taken a look at the issue as you have described it in the forums, and based on the sample code there, the simple answer is that ExchangeService is not guaranteed to be thread safe except as a public static member (see http://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.exchangeservice(v=exchg.80).aspx ).

There are various techniques you can use to avoid the issue. You could use an ExchangeService for each thread, though this may not be advisable if you have lots of threads running at once as you may well hit throttling limits (each service instance may result in a new session on the server). You could implement a cache for folder objects, so that if different threads request the same object, the cache object can return it if it has already been requested (this would also increase performance as it would reduce requests to the server).

An important point to note is that as EWS is a web application, you should use multi-threading carefully, and minimise the number of worker threads. If each of the worker threads is generating requests to the Exchange server, then you are unlikely to gain much in performance terms as compared to using one worker thread, as you will be waiting on the response from Exchange.

So the solution in my case was to create a class called "SafeExecuter" which take care that only call to the Exchange per user is made at the same time. Also it takes care that the throttlingpolicy is not exceeded.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top