title: Downloading Attachments over EWS API in C# is painfully slow - how to speed up?
body: <p>I'm using the EWS Managed API in C# to download a bunch of messages from my company's exchange server. Loading the messages themselves takes a long time considering that <code>service.FindItems()</code> only fetches limited information about the messages, but it's not a huge deal. The serious problem I'm facing is how long it takes to load attachments.</p>
  
  <p>The program is supposed to display an email and its image attachment side-by-side. When loading a new email, it can take well over a minute for the attachment to load. I initially fetched the attachments for each message when the message was loaded, but I thought it would be better to try to load them all at once into a <code>List&lt;EmailMessage&gt;</code> so the program wouldn't have to fetch the attachments when loading individual messages.</p>
  
  <p>Here's the code I used to do that:</p>
  
  <pre><code>        fetchView.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
  
          fetchView.Traversal = FolderTraversal.Deep;
  
          //create itemView for actual message query since we finally found the damn folder
          ItemView iView = new ItemView(int.MaxValue);
  
          FolderId sharedInboxFolder = new FolderId(WellKnownFolderName.Root, sharedMailbox);
          FolderId targetFolder = new FolderId(WellKnownFolderName.Root, sharedMailbox);
  
  
  
          FindFoldersResults inboxFolders = service.FindFolders(sharedInboxFolder, fetchView);
          bool folderFound = false;
  
          //look through the folders in the inbox to find the user-specified one by name
          foreach(Folder f in inboxFolders)
          {
              if (f.DisplayName == Properties.Settings.Default.InboxFolder)
              {
                  targetFolder = f.Id;
                  folderFound = true;
  
              }
          }
  
  
          // Set itemview properties for FindItems() operation
          fullProperties.Add(ItemSchema.Body);
          fullProperties.Add(ItemSchema.Attachments);
          fullProperties.Add(ItemSchema.DateTimeReceived);
          fullProperties.Add(ItemSchema.Subject);
  
  
          if (!folderFound)
          {
              MessageBox.Show("Folder not found!");
          } else {
  
              SearchFilter greaterthanfilter = new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, searchDate);
              SearchFilter lessthanfilter = new SearchFilter.IsLessThan(ItemSchema.DateTimeReceived, searchDate.AddDays(1));
              SearchFilter dayFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, greaterthanfilter, lessthanfilter);
  
              FindItemsResults&lt;Item&gt; fetchedMessages = service.FindItems(targetFolder, dayFilter, iView);
  
              foreach (Item i in fetchedMessages.Items)
              {
                  EmailMessage msg = EmailMessage.Bind(service, i.Id, fullProperties);
                  emails.Add(msg);
              }
          }
      }
  </code></pre>
  
  <p>I then save all the attachments to disk with</p>
  
  <pre><code>for (int i = 0; i &lt; message.Attachments.Count; i++)
              {
                  if (message.Attachments[i] is FileAttachment)
                  {
                      FileAttachment att = message.Attachments[i] as FileAttachment;
                      att.Load();
                      using (FileStream attStream = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Program\images\" + i.ToString(), FileMode.Create, FileAccess.ReadWrite))
                      { 
                          att.Load(attStream);
                          attStream.Close();
                          attStream.Dispose();
                      }
                  }
                  else
                  {
                      MessageBox.Show("Not FileAttachment!");
                  }
  
              }
  </code></pre>
  
  <p>Then, to load an image and it's attachment, I do</p>
  
  <pre><code>imgViewer.Source = new BitmapImage(new Uri(/some/path/to/image/))
  </code></pre>
  
  <p>I suspect the hangup is during the save attachments phase. I found <a href="https://stackoverflow.com/questions/10091745/exchange-web-services-attachment-load-is-slow">this post</a> that indicated TraceFlags should be disabled, so I did <code>service.TraceFlags = TraceFlags.None</code> but that didn't seem to help at all. I'm contemplating just downloading all the attachments up front, or figuring out some kind of caching mechanism where I download the attachments of message[n+1...x] in the background while the user works on message[n], but this has limited usefulness, because the program should also let the user select an image and load it relatively instantly (i.e. much less than a minute).</p>
  
  <p>Any suggestions are much appreciated.</p>