Exchange Web Service API非常慢,但只有从WPF应用程序调用时才会这样

时间:2016-05-10 18:05:05

标签: c# wpf exchangewebservices

我正在尝试构建一个使用Exchange Web服务API查询Exchange 2010 SP2的WPF应用程序。

但是,我发现如果我使用WPF应用程序中的Exchange API,对API的调用确实很慢。实际上,它们比从命令行应用程序运行完全相同的代码要慢两个数量级(从WPF应用程序完成一些API调用需要15秒,而从命令行应用程序完成只需0.15秒)。

我使用Visual Studio 2015和Exchange Web Services托管API 2.2。

这是WPF的代码。特别是,运行速度极慢的是folder.FindFolders中对GetPathFolder的调用:

using System;
using System.Windows;
using Microsoft.Exchange.WebServices.Data;

namespace esw_testwpf
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
            service.UseDefaultCredentials = true;
            service.TraceEnabled = true;
            service.TraceFlags = TraceFlags.All;
            service.AutodiscoverUrl("myemail@company.com", RedirectionUrlValidationCallback);

            Folder baseFolder = FindFolderIdByPath(service, @"\Path\To\A\Known\PublicFolder", WellKnownFolderName.PublicFoldersRoot);
        }

        private static bool RedirectionUrlValidationCallback(string redirectionUrl)
        {
            // The default for the validation callback is to reject the URL.
            bool result = false;

            Uri redirectionUri = new Uri(redirectionUrl);

            // Validate the contents of the redirection URL. In this simple validation
            // callback, the redirection URL is considered valid if it is using HTTPS
            // to encrypt the authentication credentials. 
            if (redirectionUri.Scheme == "https")
            {
                result = true;
            }
            return result;
        }

        public static Folder FindFolderIdByPath(ExchangeService service, string path, WellKnownFolderName root)
        {
            // Specify the root folder to be searched.
            Folder rootFolder = Folder.Bind(service, root);

            return GetPathFolder(rootFolder.FindFolders(new FolderView(100)), path, "");
        }

        public static Folder GetPathFolder(FindFoldersResults results, string lookupPath, string currentPath)
        {
            foreach (Folder folder in results)
            {
                string path = currentPath + @"\" + folder.DisplayName;
                if (lookupPath.Equals(path))
                {
                    return folder;
                }

                if (lookupPath.StartsWith(path))
                {
                    return GetPathFolder(folder.FindFolders(new FolderView(100)), lookupPath, path);
                }
                else
                {
                    continue;
                }
            }
            return null;
        }
    }
}

这就是命令行的完全相同的代码,它始终以非常快的速度运行。

using System;
using Microsoft.Exchange.WebServices.Data;

namespace ewstestcmd
{
    class Program
    {
        static void Main(string[] args)
        {
            var service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
            service.UseDefaultCredentials = true;
            service.TraceEnabled = true;
            service.TraceFlags = TraceFlags.All;
            service.AutodiscoverUrl("myemail@company.com", RedirectionUrlValidationCallback);

            Folder baseFolder = FindFolderIdByPath(service, @"\Path\To\A\Known\PublicFolder", WellKnownFolderName.PublicFoldersRoot);
        }

        private static bool RedirectionUrlValidationCallback(string redirectionUrl)
        {
            // The default for the validation callback is to reject the URL.
            bool result = false;

            Uri redirectionUri = new Uri(redirectionUrl);

            // Validate the contents of the redirection URL. In this simple validation
            // callback, the redirection URL is considered valid if it is using HTTPS
            // to encrypt the authentication credentials. 
            if (redirectionUri.Scheme == "https")
            {
                result = true;
            }
            return result;
        }

        public static Folder FindFolderIdByPath(ExchangeService service, string path, WellKnownFolderName root)
        {
            // Specify the root folder to be searched.
            Folder rootFolder = Folder.Bind(service, root);

            return GetPathFolder(rootFolder.FindFolders(new FolderView(100)), path, "");
        }

        public static Folder GetPathFolder(FindFoldersResults results, string lookupPath, string currentPath)
        {
            foreach (Folder folder in results)
            {
                string path = currentPath + @"\" + folder.DisplayName;
                if (lookupPath.Equals(path))
                {
                    return folder;
                }

                if (lookupPath.StartsWith(path))
                {
                    return GetPathFolder(folder.FindFolders(new FolderView(100)), lookupPath, path);
                }
                else
                {
                    continue;
                }
            }
            return null;
        }
    }
}

如果代码基本相同,为什么在Exchange API响应时间内会出现这种不同的行为?

我首先认为这是某种服务器端限制,但我认为WPF变体总是非常慢并且命令行变体总是很快。

1 个答案:

答案 0 :(得分:2)

当我改变时:

service.TraceEnabled = true;

service.TraceEnabled = false;

WPF中的所有额外延迟都消失了。因此,出于某种原因,似乎在WPF中启用EWS跟踪会带来巨大的性能损失。