0

在我的应用程序中,我打开了大约 70 台服务器的连接,每台服务器平均有 8 个数据库(服务器分为开发、生产、UaT、坐、培训、杂项、Qa 等环境)。应用程序将检查每个数据库中是否存在用户,如果用户存在,则获取详细信息。我使用了一种方法来调用服务,该方法将用户 ID 作为输入传递,服务将检查数据库中的用户并获取详细信息。整个过程花费了太多时间,UI 中的空闲时间约为 5-10 分钟。

我们如何调整这个应用程序的性能。我想到了在环境基础上实现多线程和获取detains。但我不确定我们是否可以在应用程序中调用具有返回类型和输入参数的方法。

请提出一种提高性能的方法。

public List<AccessDetails> GetAccessListOfMirror(string mirrorId,string server)
        {
            List<AccessDetails> accessOfMirror = new List<AccessDetails>();
            string loginUserId = SessionManager.Session.Current.LoggedInUserName;
            string userPassword = SessionManager.Session.Current.Password;
            using (Service1Client client = new Service1Client())
            {
                client.Open();
                    accessOfMirror = client.GetMirrorList(mirrorId, server, loginUserId, userPassword);
            }

            return accessOfMirror;
        }

服务方式

public List<AccessDetails> GetMirrorList(string mirrorId, string server, string userId, string userPassword)
        {

            string mirrorUser = mirrorId.ToString();
            List<ConnectionStringContract> connectionStrings = new List<ConnectionStringContract>();
            try
            {
                connectionStrings = GetConnectionString(server);
            }
            catch (FaultException<ServiceData> exe)
            {
                throw exe;
            }

            AseConnection aseConnection = default(AseConnection);
            List<AccessRequest> mirrorUsers = new List<AccessRequest>();
            List<FacetsOnlineAccess> foaAccess = new List<FacetsOnlineAccess>();
            List<AccessDetails> accessDetails = new List<AccessDetails>();
            AccessDetails accDetails = new AccessDetails();                            
            AccessRequest access;
            if (!String.IsNullOrEmpty(server))
                connectionStrings = connectionStrings.Where(x => x.Server == server).ToList();
            foreach (ConnectionStringContract connection in connectionStrings)
            {
                string connectionString = connection.ConnectionString;

                AseCommand aseCommand = new AseCommand();
                using (aseConnection = new AseConnection(connectionString))
                {
                    try
                    {
                        aseConnection.Open();
                        try
                        {
                            List<Parameter> parameter = new List<Parameter>();
                            Parameter param;
                            param = new Parameter();
                            param.Name = "@name_in_db";
                            param.Value = mirrorUser.ToLower().Trim();
                            parameter.Add(param);
                            int returnCode = 0;
                            DataSet ds = new DataSet();
                            try
                            {
                                ds = DataAccess.ExecuteStoredProcedure(connectionString, Constant.SP_HELPUSER, parameter, out returnCode);
                            }
                            catch (Exception ex)
                            {

                            }
                            if(ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                            {
                                foreach (DataRow row in ds.Tables[0].Rows)
                                {
                                    access = new AccessRequest();
                                    if (row.ItemArray[0].ToString() == mirrorUser)
                                        access.Group = row.ItemArray[2].ToString();
                                    else
                                        access.Group = row.ItemArray[0].ToString();
                                    access.Environment = connection.Environment.Trim();
                                    access.Server = connection.Server.Trim();
                                    access.Database = connection.Database.Trim();
                                    mirrorUsers.Add(access);
                                }                               

                            }


                        }
                        catch (Exception ex)
                        {

                        }
                    }
                    catch (Exception ConEx)
                    {

                    }
                }
            }
            accDetails.AccessList = mirrorUsers;
            //accDetails.FOAList = foaAccess;
            accessDetails.Add(accDetails);
            return accessDetails;
        }

提前致谢

4

2 回答 2

1

循环有时会降低速度,尤其是循环内的循环。I/O 操作总是很慢。你有一个带有 i?o 的循环。因此,如果您在并行线程上执行此 I/O 操作,性能将会提高。

你可以翻译

foreach (ConnectionStringContract connection in connectionStrings)
{
    ...
}

进入:

Parallel.ForEach(connectionStrings, connectionString =>
{
    ...
}

在里面你应该锁定常用的变量,就像mirrorUsers用锁一样。我认为这是一个很好的开始。同时我会寻找其他性能问题。

于 2013-05-01T08:52:57.107 回答
-1

您应该能够在没有太多麻烦的情况下利用多线程......

您可能应该使用线程池,因此您不会产生太多同时运行的线程。您可以在此处阅读有关内置线程池的信息:

http://msdn.microsoft.com/en-us/library/3dasc8as%28v=vs.80%29.aspx

您应该做的是将foreach循环体提取到静态方法中。任何参数都应该做成可以传递给线程的模型。因为那时您可以使用ThreadPool.QueueUserWorkItem(object)启动线程。

关于写入同一资源(列表或其他)的多个线程,您可以使用任何类型的互斥锁、锁或线程安全组件。使用锁非常简单:

http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=vs.80%29.aspx

于 2013-05-01T09:01:15.243 回答