我有一个异步ASP.Net页面(Async =“true”),代码如下。
如果在异步任务方法'DoTask1'中发生错误,那么它似乎不像其他正常错误那样由ASP.Net页面框架处理。
我尝试在EndAsyncOperation1方法中获取Server.GetLastError(),但即使在DoTask1方法中发生错误,它也会返回null。 是否有一些特殊的方法来处理异步任务中发生的错误?
protected void btnSave_Click(object sender, EventArgs e)
{
PageAsyncTask pagetask1 = new PageAsyncTask(new BeginEventHandler(BeginAsyncOperation1),
new EndEventHandler(EndAsyncOperation1),
new EndEventHandler(TimeoutAsyncOperation1),
new object[] { employeeId, totalEarnings }, true);
RegisterAsyncTask(pagetask1);
}
//Async Task method below is called by the registered task
private void DoTask1(object[] paras)
{
//line below throws an exception on the async task thread
string x = null;
string y = x.Trim();
//More code come here
}
IAsyncResult BeginAsyncOperation1(object sender, EventArgs e, AsyncCallback cb, object state)
{
task1 = new AsyncTaskDelegate(DoTask1);
IAsyncResult result = task1.BeginInvoke(state as object[], cb, "task1");
return result;
}
void EndAsyncOperation1(IAsyncResult ar)
{
task1.EndInvoke(ar);
if (success1 == null)
{
success1 = true;
}
}
void TimeoutAsyncOperation1(IAsyncResult ar)
{
success1 = false;
}
答案 0 :(得分:0)
我终于找到了问题的答案。
在使用Async =“true”标记的ASP.Net页面中处理异步任务错误时,可以遵循2种方法。请注意,此问题中代码调用的asyn任务方法是“DoTask1”。
APPROACH 1:不要将任何内容包含在try catch中,即使是作为异步任务执行的代码,因为默认的ASP.Net错误处理将在ASP.Net中发挥作用。因此,如果您的页面作为ajax回发回发,那么ScriptManager的AsynError事件将触发,您可以在此事件中执行任何您喜欢的操作,或者如果其非ajax回发然后在页面级别使用Page_Error事件来处理错误。示例代码如下所示。
在我的情况下,Server.GetLastError返回null,因为我在ScriptManager的AsyncError事件中清除了错误(即Server.ClearError)。
protected void radScriptManager_AsyncPostBackError(object sender,
System.Web.UI.AsyncPostBackErrorEventArgs e)
{
//log the exception using ELMAH or any other logging mechanism
Exception ex = Server.GetLastError() ;
if (ex != null)
{
Exception bex = ex.GetBaseException();
if (bex != null)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(bex);
}
}
Server.ClearError();
}
方法2:第二种方法涉及在try catch中的EndAsyncOperation1中调用EndInvoke方法。 EndInvoke方法的优点在于它重新抛出异步任务方法(即'DoTask1')上发生的异常,因此我们可以捕获它并处理它,如下面的代码所示。在这种情况下,我使用ELMAH来记录和处理错误,但您可以使用任何记录机制。
在使用第二种方法时,没有必要将代码放在try catch中的异步任务方法中,因为如果在异步方法中发生错误,那么它将自动传播到EndInvoke方法。
void EndAsyncOperation1(IAsyncResult ar)
{
try
{
task1.EndInvoke(ar);
success1 = true;
}
catch (Exception e1)
{
success1 = false;
//log the exception (this will log error and also send out an error email)
Elmah.ErrorSignal.FromCurrentContext().Raise(e1);
}
if (success1 == null)
{
success1 = true;
}
}