title: Null reference - Task ContinueWith()
body: <p>For the following piece of code (.NET v4.0.30319) I am getting a null reference exception indicated below in the second continuation.</p>
  
  <p>Most interestingly this issue has only occurred in machines with 8GB RAM but other users have 16GB and more and they haven't reported any issue, and it is a very intermittent issue which leads me to suspect a garbage collection issue. </p>
  
  <p>The <code>GetData()</code> can be called multiple times so the first continuation of _businessObjectTask will only be called once as _businessObjects will have been populated from that point forward.</p>
  
  <p>I imagine the <code>Object reference not set to an instance of an object</code> exception is being thrown because either </p>
  
  <ol>
  <li><code>_businessObjectTask</code> is null and it can't continue from a null task. </li>
  <li><code>items</code> variable which is passed in as a parameter is null somehow</li>
  </ol>
  
  <p>The line number in my log file (748) points to the one highlighted below and not the lambda expression which points to #1 above instead of #2. I've played around in Visual Studio and each of the lines following <code>businessObjectTask.ContinueWith()</code> are considered different i.e. if it was a null reference within the lambda expression it would give a different line number to 748</p>
  
  <p>Any help would be greatly appreciated. </p>
  
  <p>Edit:
  This isn't related to <a href="https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it">What is a NullReferenceException, and how do I fix it?</a> because that is a much more basic explanation of null reference whereas this is much more complicated and subtle. </p>
  
  <p><strong>Exception</strong></p>
  
  <p>Full details of the stack trace (edited for simplicity with dummy class and namespace names)</p>
  
  <pre><code>Object reference not set to an instance of an object.
     at ApplicationNamespace.ClassName`1.&lt;&gt;c__DisplayClass4e.&lt;GetData&gt;b__44(Task`1 t) in e:\ClassName.cs:line 748
     at System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
     at System.Threading.Tasks.Task.Execute()
  </code></pre>
  
  <p><strong>Code</strong></p>
  
  <pre><code>private static IDictionary&lt;string, IBusinessObject&gt; _businessObjects;
  private Task&lt;IDictionary&lt;string, IBusinessObject&gt;&gt; _businessObjectTask;
  
  public Task GetData(IList&lt;TBusinessItem&gt; items))
  {
      Log.Info("Starting GetData()");
  
      if (_businessObjects == null)
      {
          var businessObjectService = ServiceLocator.Current.GetInstance&lt;IBusinessObjectService&gt;();
  
          _businessObjectTask = businessObjectService.GetData(CancellationToken.None)
          .ContinueWith
          (
              t =&gt; 
              {
                  _businessObjects = t.Result.ToDictionary(e =&gt; e.ItemId);
  
                  return _businessObjects;
              },
              CancellationToken.None,
              TaskContinuationOptions.OnlyOnRanToCompletion,
              TaskScheduler.Current
          );
      }
  
  
      var taskSetLEData = _businessObjectTask.ContinueWith // Line 748 in my code - "Object reference not set to an instance of an object." thrown here
      (
          task =&gt;
          {
              items.ToList().ForEach
              (
                  item =&gt;
                  {
                      IBusinessObject businessObject;
  
                      _businessObjects.TryGetValue(item.Id, out businessObject);
                      item.BusinessObject = businessObject;
                  }
              );
          },
          CancellationToken.None,
          TaskContinuationOptions.OnlyOnRanToCompletion, 
          TaskScheduler.Default
      );
  }
  </code></pre>
  
  <p><strong>Resolution:</strong></p>
  
  <p>So having used what I've learned from this question I went back to the original code and figured it all out.</p>
  
  <p>Turns out the reason for this NRE was because the <code>_businessObjectTask</code> is non-static where as the <code>_businessObjects</code> is static.</p>
  
  <p>This means that <code>_businessObjects</code> is null the first time <code>GetData()</code> is called which then sets <code>_businessObjectTask</code> to non-null. Then when <code>_businessObjectTask.ContinueWith</code> gets called it is non-null and continues without problem. </p>
  
  <p>However if a second instance of this class above is instantiated, <code>_businessObjects</code> has already been populated so <code>_businessObjectTask</code> remains null. Then when <code>_businessObjectTask.ContinueWith</code> gets called, a NRE on <code>_businessObjectTask</code> is thrown.</p>
  
  <p>There were a couple of options I could have taken but I ended up removing the <code>_businessObjectTask</code> to a synchronous method call which means that I dont need to use the continuation anymore and I set <code>_businessObjects</code> once.</p>