Search code examples
c#linqdebugginginversion-of-controldeferred-execution

Trying to view properties in debug gives different counts after time delay. Is this due to deferred execution?


I have the following method in a class:

public IPlayerInfo GetPlayerInfo(int playerId)
{
    return GetPlayerDetails(playerId).Matches; // Matches have Runs and Wickets list
}

And I have a class as follows:

public class MyClass
{
  public Lazy<IMyInterface> _service1;

  public MyClass(Lazy<IMyInterface> service1)
  { 
    _serivce1 = service1;
  }

  public void SomeMethod()
  {
    var runsList = _serivce1.GetPlayerInfo(1).Runs; // debugging this line of code
  }
}

When I tried to debug the above code,

  • I watched the value of _serivce1.GetPlayerInfo(1) using quick watch (Shift + F9). I expanded all its child nodes. One of its child nodes is Runs. I expanded Runs. It showed Expanding the Results View will enumerate the IEnumerable. I enumerated it. It was empty.
  • I didn't close debugging
  • After sometime, when I pressed shift + F9 and viewed it again in quick watch, it had one item added after I enumerated the IEnumerable. Magic!
  • After sometime, when I pressed shift + F9 and viewed it again in quick watch, it had the second item added after I enumerated the IEnumerable. Magic square!!
  • Then, as _serivce1.GetPlayerInfo(1).Runs had two items added, instead of loading _serivce1.GetPlayerInfo(1) and expanding the child node Runs, I tried to debug _serivce1.GetPlayerInfo(1).Runs directly but it was empty :(

When I ran without debug, _serivce1.GetPlayerInfo(1).Runs (and so the runsList) had no itmes at all. Please let me know if this is due to deferred execution. Also, please let me know the solution for this.


Solution

  • It is not deferred execution, it is simply Quickview running code in the normal way.

    There is no "solution" to this type of side effects besides not using Quickview or possibly start using OzCode that describes how they have circumvented at least some kind of side effects.

    Something, somewhere, adds 1 to Runs. This something is run when you execute _serivce1.GetPlayerInfo(1).

    Either (1) find this place and set a breakpoint
    or (2) set a breakpoint in GetPlayerInfo.
    Then write ? _serivce1.GetPlayerInfo(1) in the Immediate window.
    Contrary to Quickview, the Immediate window triggers breakpoints.

    Doing (1) should stop executing in your breakpoint
    while (2) lets you debug-step-into until you find the place of the add.