c# - 在异步 ASP.Net 页面中处理来自异步任务的错误

标签 c# asp.net asynchronous

我有一个异步 ASP.Net 页面 (Async="true"),代码如下。

如果在异步任务方法“DoTask1”中发生错误,那么它似乎不像其他正常错误那样由 ASP.Net 页面框架处理。

我尝试在 EndAsyncOperation1 方法中获取 Server.GetLastError(),但即使在 DoTask1 方法中发生错误,它也会返回空值。 是否有一些特殊的方法来处理异步任务中发生的错误?

    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;
    }

最佳答案

我终于找到了问题的答案。

在用 Async = "true"标记的 ASP.Net 页面中处理异步任务错误时,可以采用两种方法。请注意,此问题中代码调用的异步任务方法是“DoTask1”。

  • 方法 1: 不要在 try catch 中包含任何内容,即使是作为异步任务执行的代码,因为默认的 ASP.Net 错误处理将在 ASP.Net 中发挥作用.因此,如果您的页面作为 ajax 回发回发,那么 ScriptManager 的 AsynError 事件将触发,您可以在此事件中做任何您想做的事情,或者如果它的非 ajax 回发则在页面级别使用 Page_Error 事件来处理错误.示例代码如下。

    在我的例子中,Server.GetLastError 返回了一个空值,因为我正在清除 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:第二种方法涉及将对 EndAsyncOperation1 中的 EndInvoke 方法的调用放在 try catch 中。 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;
        }
    }
    

关于c# - 在异步 ASP.Net 页面中处理来自异步任务的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23714918/

相关文章:

C# 将 MemoryStream 转换为 FileStream

c# - Asp.Net Core Web Api 中端点之间的内存缓存似乎有所不同

c# - 如何解决 Enumerable 和 MoreLINQ 之间不明确的 ZIP 调用?

asp.net - 什么时候会调用 InitializeCulture

ASP.NET SQL Server session 状态非常慢

node.js - 与异步系列控制流混淆

c# - ASP.Net Core 验证问题状态 - 绑定(bind)验证不返回问题详细信息

c# - 操纵形式. Action

javascript - 如何在 react 类之外访问纯 js 值

Windows 重叠 IO 与单独线程上的 IO