我一次又一次面对以下问题,我不知道如何解决它..
我经常收到以下错误,我必须restart the IIS
或republish
暂时解决问题:
Error Message:Request timed out.
Error Message:ERROR [08S01] [Informix .NET provider]Communication link failure.
Error Message:Thread was being aborted.
我尝试制作:
<httpRuntime executionTimeout="600" />
但仍然是同样的问题!!
Stack Trace:
at System.Web.HttpContext.InvokeCancellableCallback(WaitCallback callback, Object state)
at System.Web.UI.Page.AsyncPageBeginProcessRequest(HttpContext context, AsyncCallback callback, Object extraData)
at ASP.appmaster_aspx.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object data)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
我的PageLoad:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["emp_num"] != null && !string.IsNullOrEmpty(Session["emp_num"].ToString()))
{
try
{
string user_setting = Personalization_DAL.CheckWidgetSettings(int.Parse(Session["emp_num"].ToString()));
if (!string.IsNullOrEmpty(user_setting))
{
user_flag = int.Parse(user_setting);
}
GetLinkedApp = DB_Connection_s.DB_Connection.GetLinkedAppUser(int.Parse(Session["emp_num"].ToString()));
if (!Page.IsPostBack)
{
//Profile
GetProfile();
if (Session["emp_app"] != null && !string.IsNullOrEmpty(Session["emp_app"].ToString()))
{
BindAvailableSystems(Session["emp_app"].ToString());
}
BindMainSystems();
if (GetLinkedApp > 0)
{
rlv_available_sys.Visible = true;
h5_app.Visible = true;
lbtn_addApp.Visible = false;
h4_app.Visible = false;
intro.Visible = true;
}
else
{
rlv_available_sys.Visible = false;
h5_app.Visible = false;
lbtn_addApp.Visible = true;
h4_app.Visible = true;
intro.Visible = false;
}
//Applications
if (rlv_available_sys.Visible == true)
{
Session["emp_app"] = GetLinkedApp;
BindAvailableSystems(Session["emp_app"].ToString());
if (user_flag > 0)
{
Get_UserApplicationSystems(1, 1, GetLinkedApp.ToString());
}
else
{
Get_UserApplicationSystems(user_flag, 1, GetLinkedApp.ToString());
}
}
//services
Get_MainSystems(user_flag);
if (GetLinkedApp > 0)
{
GetServiceInformation();
}
string[] statistics = TrackUser();
base.TraceActivity("Enter the portal", "https://" + Request.Url.Authority + "/AppMaster.aspx", statistics[0], statistics[1], statistics[2]);
}
TraceSystemsMode();
}
catch (Exception ee)
{
string message = ee.Message;
}
}
else
{
Response.Redirect("LoginPage.aspx", false);
}
}
我的通用处理程序:
public void ProcessRequest(HttpContext context)
{
try
{
using(Stream photo_stream = Photo_DAL.RetrievePhoto(int.Parse(context.Session["emp_num"].ToString())))
{
byte[] photo_bytes = Photo_DAL.StreamToByteArray(photo_stream);
if (photo_bytes == null)
{
photo_bytes = File.ReadAllBytes(Path.Combine(context.Server.MapPath("~/images/PortalImages/"), "user.png"));
}
//context.Response.ContentType = "image/png";
context.Response.BinaryWrite(photo_bytes);
}
}
catch (Exception ee)
{
}
}
答案 0 :(得分:9)
这是猜测,因为我们无法从问题中发布的片段中看到很多引用的代码。
我将假设您没有正确处理数据库连接(DB_Connection_s
),原因有两个。
A)通过重置修复
I get the following errors frequently , and i had to restart the IIS or
republish to fix the problem temporary`
对我而言,这表明您正在使用数据库的所有连接,因为当您重新启动或重新发布时,所有当前连接都将被删除。
B)没有明确处置
在你的代码中,你引用DB_Connection_s
,但它没有包含在using块中,并且它没有被实例化,这意味着它很可能是一个静态类或方法(很难说没有代码用于该引用)。
<强>建议强>
确保始终正确处理数据库连接。他们 NEED 在完成后调用.Dispose()。这通常是通过获取包含上下文的类并使其实现IDisposable
,然后使用using语句将所有调用该类包含在该类中来完成的。 using语句将自动调用Dispose
方法。如果您不想实现IDisposable
,那么在查询完成后,您可以通过直接在连接上调用.Dispose()
来明确(未建议)处理数据库连接。
根据新添加的评论进行修改:
@just_name - 从评论中的代码来看,在我看来可能存在问题。依靠~DBConnection()
处理您的连接,只调用.Close()
而不是关闭流,这对我来说非常突出。
i)终结者可能需要很长时间
使用终结器处理连接可能会有风险,因为您无法确切地确定何时调用它。 “在垃圾收集期间终结器执行的确切时间是未定义的。” - MSDN Object.Finalize。这可能导致系统等待很长时间,如果它有很多资源,然后再处理任何连接,从而减慢请求的速度。
ii)关闭不是Dispose
虽然在技术上可以安全地在连接上调用.Close()
,但它可能会导致生产出现问题。原因是连接将关闭,但事件处理程序将保留,有时如果涉及延迟加载或动态代理,这些事件处理程序可以保存连接的副本。
iii)使用Dispose
a)明确处理您的连接
始终明确处理您的连接,不要等待垃圾收集器执行此操作。处理它的最佳实践方法是在访问using(){}
类时使用DBConnection
块。您可以进行一些更改来执行此操作:
定义DBConnection以实现IDisposable,以便可以在using block
中使用它public class DBConnection : IDisposable
{
//other methods already in here
public void Dispose()
{
//Close_Connection(); Call this if you want, but you MUST call
//.Dispose on your connections
connection.Dispose();
}
}
这将允许您创建一个新的DBConnection:
using( var DB_Connection_s = new DBConnection() )
{
//todo: interact with database connection
}
当达到最终.Dispose()
时,使用块将自动调用}
并保证连接处置。此外,这允许数据库发生较小的事务时间,如果涉及数据库访问的任何排队,则可以提高查询和请求速度。
如果您不喜欢使用块实现,那么至少要将.Close()
更改为.Dispose()
您使用关闭的所有位置,并确保没有可能的执行路径导致数据库访问完成后不立即调用.Dispose()
。
b)在非托管资源上使用.Dispose()
始终在非托管资源上使用.Dispose()
。有几种方法可以做到这一点,但最佳实践方法是使用using(){}
块。我注意到你可以在一个地方实现这一点,特别是你的代码中必须处理的流。
这是一段令人讨厌的代码:
IfxDataReader ifxDataReaders = DB_Connection.DBCmd.ExecuteReader();
if (ifxDataReaders.Read()) {
item = (int)ifxDataReaders["emp_num"];
}
ifxDataReaders.Close();
我对此有几个问题。首先,您正在调用上面讨论过的.Close()
。其次,因为这是一个try块,ifxDataReaders可能会抛出异常,程序将继续运行而不会关闭或处理读取器。这可能会导致很多问题。
您应该做的是确保在非托管资源上调用.Dispose
始终。您可以使用using块(隐式总是调用.Dispose()
)来执行此操作。
using(IfxDataReader ifxDataReaders = DB_Connection.DBCmd.ExecuteReader())
{
if (ifxDataReaders.Read()) {
item = (int)ifxDataReaders["emp_num"];
}
}
答案 1 :(得分:2)
我知道它不属于Error Message:Request timed out
,但它可能与Error Message:Thread was being aborted.
有关联。因此,由于我们没有任何代码示例,我认为当它在Try-Catch块内部进行时,可以认为它可能是Response.Redirect("aPage.aspx")
问题。
如果是您的情况,请尝试在Response.Redirect
方法的EndResponse参数中添加“False”,如下所示:
try {
// [... SOME CODE ...]
Response.Redirect("aPage.aspx", False)
} catch (Exception e) {
// [... YOUR CATCH ...]
}
答案 2 :(得分:2)
所以我投了Zia的评论,建议你单独运行这些部分以隔离超时。 Informix连接是否有可能出错?
数据库查询有两个超时,即连接超时和命令超时。这些都不会使用 executionTimeout 值。我没有尝试使用Informix提供程序,但是如果服务器繁忙或命令对象等待长SQL查询运行,我已经增加了连接对象的超时。
这是在Informix连接对象上设置connectionTimeout的链接... http://publib.boulder.ibm.com/infocenter/idshelp/v115/index.jsp?topic=%2Fcom.ibm.net_cc.doc%2Fcom.ibm.swg.im.dbclient.adonet.ref.doc%2Fdoc%2FDB2ConnectionClassConnectionTimeoutProperty.htm
答案 3 :(得分:2)
主要问题是,为什么需要这么长时间?为什么有些人会在一页上花费超过30秒?你能真的和这么慢的网站一起生活吗?
我们必须了解如何降低性能,以便请求在30秒内完成。
你能分享代码吗?让我们看看代码瓶颈在哪里。