gpt4 book ai didi

c# - 线程池饥饿

转载 作者:太空宇宙 更新时间:2023-11-03 16:28:19 24 4
gpt4 key购买 nike

我的问题与负载增加时阻塞的 aspx.net 4.0 Web 服务器有关。通过阻止我的意思是请求是由客户端发送的,但响应在大约 45 秒后返回。这在开发和生产环境中是可重现的。这 45 秒似乎是恒定的,我在调用 Constructor() 和 void Render(HtmlTextWriter writer) 之间在客户端和 aspx 页面中测量了这一点。我在一页上总共使用了几个 SqlDataSources 和使用 6 个 SqlCommand.BeginExecuteReader(...) 的自定义控件。如果我使用 BeginExecuteReader/EndExecuteReader 模式停用控件,我就可以消除该问题。因此,我假设最终 BeginExecute 调用之一会被阻塞,直到 ThreadPool 中有线程可用。

我打印调试消息并识别出一种模式,即总是在返回阻塞请求之前打印一堆线程退出消息:

The thread 'GetMolFileAsync' (0x1ba4) has exited with code 0 (0x0).

The thread 'GetMolFileAsync' (0x27d0) has exited with code 0 (0x0).

The thread '' (0x23c) has exited with code 0 (0x0).

The thread 'GetCompoundDepositionInfo' (0x1e88) has exited with code 0 (0x0).

The thread 'GetMolFileAsync' (0x2758) has exited with code 0 (0x0).

0x43 27/07/2012 15:09:42 45 ==> blocked thread took 45 seconds

0x5F 27/07/2012 15:10:27 0 ==> normal behaviour, processed in some miliseconds

...

这是向数据库发起请求的方法

public static IAsyncResult GetCompoundDepositionInfoAsync(object sender, EventArgs e, AsyncCallback callback, object state)
{
GetCompoundVersionInfoAsyncParameters parameters = (GetCompoundVersionInfoAsyncParameters)state;
IAsyncResult res = null;

parameters.cmd = new System.Data.SqlClient.SqlCommand("www.GetCompoundDepositionInfo", new System.Data.SqlClient.SqlConnection(parameters.connectionstring));
parameters.cmd.CommandType = System.Data.CommandType.StoredProcedure;
parameters.cmd.Parameters.AddWithValue("@CompoundID", parameters.CompoundID);
try
{
parameters.cmd.Connection.Open();
res = parameters.cmd.BeginExecuteReader(callback, parameters, System.Data.CommandBehavior.CloseConnection);
}
catch (Exception ex)
{
if (parameters.cmd.Connection.State == System.Data.ConnectionState.Open)
{
parameters.cmd.Connection.Close();
}
throw new Exception("Exception in calling GetCompoundDepositionInfoAsync()", ex);
}
return res;
}

这是回调函数

public void GetCompoundDepositionInfoCallback(IAsyncResult result)
{
gmdTools.GmdCompound.GetCompoundVersionInfoAsyncParameters param = (gmdTools.GmdCompound.GetCompoundVersionInfoAsyncParameters)result.AsyncState;

System.Threading.Thread.CurrentThread.Name = "GetCompoundDepositionInfo";
using(System.Data.SqlClient.SqlCommand command = param.cmd)
using(System.Data.SqlClient.SqlDataReader reader = command.EndExecuteReader(result))
{
try
{
if (reader.Read())
{
lblDeposited.Text = string.Concat("at ", reader.GetDateTime(0).ToShortDateString(), " by ", reader.GetString(1));
}
}
finally
{
if (reader != null)
{
reader.Close();
command.Connection.Close();
}
}
}
}

这是将它们粘合在一起的代码...

Page.RegisterAsyncTask(new PageAsyncTask(
new BeginEventHandler(gmdTools.GmdCompound.GetCompoundLastChangeInfoAsync)
, new EndEventHandler(GetCompoundLastChangeInfoCallback)
, new EndEventHandler(GetCompoundInfoAsyncTimeout)
, new gmdTools.GmdCompound.GetCompoundVersionInfoAsyncParameters()
{
connectionstring = Properties.Settings.Default.GmdConnectionString,
CompoundID = CompoundId,
}, true
));

由于我已经花了数小时查看此代码,因此我将不胜感激任何反馈。

更新这 45 秒由默认 Page.AsyncTimeout 决定,可以使用 Async="true"AsyncTimeout="10" 语句更改为 10 秒。虽然我通过添加适当的索引大大提高了网站的整体性能,但在服务器发送响应之前,客户端有时不得不等待这段时间。在这种情况下,不会调用 AsyncTimeout 处理程序。我假设该页面注册了所有异步操作,但最终没有识别出某些异步操作已成功完成,因此在呈现页面之前等待 AsyncTimeout 秒。对此有何评论?

最佳答案

它可能是数据库,给定查询返回的选择或行,它选择的是多于还是少于千分之一? MS SQL will change the way it operates when the choice goes through 1 in 1000 rows returned.如果使用 SQL 事件探查器运行查询,是否进行表扫描?如果您运行内置的 sp 来确定缺失的索引,它会返回对这些表的索引的请求吗?您的统计数据是最新的吗?对此的线索是恢复的备份可以快速运行查询,因为当您恢复备份时,统计信息会更新。您的(所有/每个)表上是否有聚簇索引?

这个答案也可能是相关的 Entity Framework MVC Slow Page Loads

关于c# - 线程池饥饿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11691041/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com