C#中的空指针异常

时间:2012-11-21 10:57:32

标签: c# c#-4.0 asynchronous

我在下面的代码中遇到NullPointerException,因为它很少发生,我试图调试来复制问题,但没有运气。任何人都可以帮助我在这里导致NullPointerException。

private static void MyTaskCompletedCallback(IAsyncResult res)
    {
        var worker = (AsyncErrorDelegate)((AsyncResult)res).AsyncDelegate;
        var async = (AsyncOperation)res.AsyncState;
        worker.EndInvoke(res);
        lock (IsAsyncOpOccuring)
        {
            IsBusy = false;
        }
        var completedArgs = new AsyncCompletedEventArgs(null, false, null);
        async.PostOperationCompleted(e => OnTaskCompleted((AsyncCompletedEventArgs)e), completedArgs);
    }

报告空指针异常 var async =(AsyncOperation)res.AsyncState;

我调用它的代码

 var context = HttpContext.Current;
        AsyncErrorDelegate bkWorker = SendErrorMail;
        AsyncCallback completedCallback = MyTaskCompletedCallback;
        lock (IsAsyncOpOccuring)
        {
            if (IsBusy)
            {
                //Do we need to do something if repeated async getting call in case of error occuring at same time by different users.

            }

            AsyncOperation async = AsyncOperationManager.CreateOperation(null);
            bkWorker.BeginInvoke(context,completedCallback, async);
            IsBusy = true;
        }

2 个答案:

答案 0 :(得分:1)

应该

var async = (AsyncOperation)asyncResult.AsyncState;

不是

var async = (AsyncOperation)res.AsyncState;

答案 1 :(得分:1)

  

var async = (AsyncOperation)res.AsyncState;

报告空指针异常

我们可以从逻辑上推断出事实并非如此。

如果该行之前有效,我们知道res不为空。 AsyncStateobject,因此这里不涉及自定义运算符,这意味着强制转换是一种类型检查 - 可以返回null(没有错误),也可以引发无效 - 播出例外。

如果您看到NullReferenceException,则会留下2个选项:

  • res为空,上面的行是错误的(其中:我们实际上不应该期望 - 这不会发生)
  • 错误实际上来自EndInvoke
  • 之后的

(当涉及异常时,确切的行经常会有些混淆)。

我建议你在每个之间添加日志,以跟踪发生的事情。我还建议您在try周围明确EndInvoke,因为这会抛出异常(它会重新抛出异步操作中的任何异常)。

在更一般的情况下,第三种选择是:

  • AsyncOperationstructAsyncStatenull

但是,在这种情况下,我们可以通过演绎来排除,因为如果AsyncOperationstruct,则以下永远不会框到null(只有一个空的AsyncOperation?会显示为null}:

AsyncOperation async = AsyncOperationManager.CreateOperation(null);
bkWorker.BeginInvoke(context,completedCallback, async);