可以使用多线程来调整我的应用程序的性能
本文关键字:应用程序 性能 我的 调整 多线程 可以使 | 更新日期: 2023-09-27 18:11:50
在我的应用程序中,我打开了大约70个服务器的连接,每个服务器平均有8个数据库(服务器分为环境:开发,生产,UaT, sit,培训,misc,Qa)。应用程序将检查每个数据库中是否存在用户,如果用户存在,则获取详细信息。我使用了一个方法来调用服务,该方法将传递用户id作为输入,然后服务将在数据库中检查用户并获取详细信息。整个过程花费了太多的时间,UI的空闲时间大约是5 - 10分钟。
我们如何调优这个应用程序的性能。我想在环境的基础上实现多线程和抓取。但是我不确定我们是否可以在应用程序中调用具有返回类型和输入参数的方法。
请建议一个提高性能的方法。
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;
}
Thanks in advance
循环有时会降低速度,尤其是循环中的循环。I/O操作总是很慢。你有一个i?o的循环。因此,如果在并行线程上执行这些I/O操作,性能将会提高。
你可以翻译
foreach (ConnectionStringContract connection in connectionStrings)
{
...
}
为:
Parallel.ForEach(connectionStrings, connectionString =>
{
...
}
在内部,您应该锁定常用的变量,如mirrorUsers
加锁。我认为这是一个很好的开始。同时,我会寻找其他性能问题。
你应该能够在没有太多麻烦的情况下利用多线程…
你可能应该利用线程池,这样你就不会产生太多的线程同时运行。你可以在这里阅读有关内置线程池的信息:
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