我的应用程序为什么调用如此缓慢?

3
我正在创建一个asp.net应用程序(我已经做过很多次)。 但这是我第一次遇到这个具体的问题。
当我在页面上第一次点击按钮(所以应用程序已经加载)时,这非常慢。
在我点击按钮之后,该页面上的所有其他调用都非常快(应该是这样的)。
我已经打开了sql profiler和charles(http debugger)来查看发生了什么,有趣的是:页面本身很慢,执行的查询总共需要约50毫秒才能执行,但是启动对数据库的调用需要18秒钟。
因此,.net代码在开始执行其sql代码之前需要非常长的时间。我真的不明白。 希望有人可以帮助我。
这是我的应用程序层如何完成的:
Masterpage -> 页面 -> 用户控件(在repeater中)-> 按钮。
按钮只执行一个服务层,该服务层将访问存储库层,该层将开始调用数据库。
以下是我得到的日志记录。
这是我的应用程序结构:
UserService -> UserRepository: RepositoryBase -> dataAccess. 代码:
public User GetByEmailAndPassword(string email, string password)
        {
            _log.Info("UserRepository.GetByEmailAndPassword - Start");
            this.Test();
            User result = null;

            List<DbParam> parameters = new List<DbParam>();
            parameters.Add(new DbParam("@Email", email, DbType.String));
            parameters.Add(new DbParam("@Password", password, DbType.String));

            _log.Info("UserRepository.GetByEmailAndPassword - Entering reader");
            var reader = ExecuteReader("User_GetByEmailAndPassword", parameters);
            if (reader.Read())
            {
                result = _entityFactory.ConvertToModel(reader);
            }

            reader.Close();

            _log.Info("UserRepository.GetByEmailAndPassword - End");

            return result;
        }

仓库基础:

public abstract class RepositoryBase<T>
        where T : IEntity
    {
        private static ILog _log = LogManager.GetLogger(typeof(RepositoryBase<T>));
        protected IEntityFactory<T> _entityFactory;

        protected RepositoryBase()
        {
            _log.Info("Constructor");
            _entityFactory = EntityFactoryBuilder.BuildFactory<T>();
        }

        protected IDataReader ExecuteReader(string storedProc, List<DbParam> parameters)
        {
            _log.Info("ExecuteReader - Start");

            _log.Info("Open connection");
            var db = DatabaseFactory.CreateDatabase();

            _log.Info("Open command");
            var dbCommand = db.GetStoredProcCommand(storedProc);

            foreach (DbParam param in parameters)
            {
                db.AddInParameter(dbCommand, param.Name, param.Type, param.Value);
            }

            _log.Info("Execute command");
            var reader = db.ExecuteReader(dbCommand);

            _log.Info("ExecuteReader - End");

            return reader;
        }
    }

记录显示,仅输入此函数就需要14秒钟。
var reader = ExecuteReader("User_GetByEmailAndPassword", parameters);

这并不是在执行函数,而只是在调用函数。

我很惊讶,我真的不知道为什么调用基类中的函数需要这么长时间。

我可以添加一些日志数据,但它只会显示我在这里所说的内容。

这可能是由于虚拟服务器造成的属性吗?
因为在非虚拟服务器上测试相同的应用程序根本没有这个问题。

谢谢, M.


当你发起调用时,你的服务层是否已启动? - Neil Knight
页面在线,我们可以看到它吗? - Aristos
@Aristos:它已经在线了,但不对公众开放(需要登录/密码保护),对此很抱歉。 - user29964
在调试模式下它是否也会有同样的问题?你能否通过调试器逐步执行代码,查看哪里花费了时间?而且,这个缓慢的请求是在页面加载后的第一个请求(即PostBack正常),还是如果你离开并回来(即对页面进行全新的请求),它仍然很慢? - Chris
在回答问题之后进行审查是不可取的... - Magnetic_dud
5个回答

2

我在工作中遇到了类似的问题。原因是网站运行的服务器是虚拟服务器。看起来你并没有执行任何CPU密集型操作(和我们的应用程序一样),因此不应该有问题。但是,对于我们来说,将应用程序放在专用服务器上确实解决了这个问题...


1

谢谢您发布这个内容,非常有帮助 :) - Gan

0
也许在 postback 时,您正在加载一些在初始 GET 时没有加载的控件,而且该控件尚未编译,因此需要很长时间来编译该控件(即包含它的 Web 网站文件夹)。
或者您可能正在对不同的页面进行 postback?
您能描述一下在 postback 上具体做了什么吗?

0

我猜CLR在第一次启动时会加载(或者编译)DLL和源代码,同时启动用于连接数据库的套接字。

你可能想在启动时初始化数据库连接,以便预热CLR以避免这种情况。

此外,我建议阅读http://msdn.microsoft.com/en-us/library/ff647787.aspx,虽然有点老,但你可能会对它感兴趣。


0
实现一个Page_Init函数并从那里检查你的时间到LoginLinkButton_Click - 你会把问题分解成页面内部或者在你的Web服务器管道中 - 如果需要很长时间才能到达Page_Init,那么Web服务器正在做一些奇怪的事情(重建dlls?),如果从page_init需要很长时间,那么你就有了问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接