Search code examples
c#backgroundworkerreturncheckpoint

C# BackgroundWorker Cancellation checkpoint shortening


Is there a way to shorten my BackgroundWorker.CancellationPending checkpoint?

For example, is there a way to encapsulate return like the example code below?:

//REAL CODE (CURRENTLY USE THIS)
if (this.TW.CancellationPending) 
    return; 

//PSEUDO REPLACEMENT CODE
this.CkPt(CurrentMethod); //PSEUDO USAGE 
    //^^^ PARAMETER IS A REFERENCE TO THE CURRENT METHOD, SIMILAR TO `this` FOR AN OBJECT  
//OR MAYBE AN EXTENSION METHOD WOULD LOOK CLEANER
CurrentMethod.CkPt(); //PSEUDO USAGE

private void CkPt(Method m) //PSEUDO METHOD
{
    /*
        POSSIBLY PERFORM OTHER CHECKPOINT TASKS HERE
    */
    if (this.TW.CancellationPending) 
        m.return/*FROM METHOD THAT CALLED ME*/;
}  

I'm trying to make multi-checkpoint situations like this more readable:

//PSUEDO METHOD 
//DO NOT TAKE THIS AS REPEATING CODE
//IT IS ONLY MEANT TO SHOW MULTIPLE USES OF THE SAME CHECKPOINT
//MY REAL TASK METHOD(S) CONTAIN MANY MANY MANY AREAS THAT DON'T REPEAT AND REQUIRE CHECKPOINTS  
public void FakeBWTask()
{
    if (this.TW.CancellationPending) 
        return; 

    foreach (var F1 in Fake1)
    {
        if (this.TW.CancellationPending) 
            return; 

        foreach (var F2 in Fake2)
        {   
            if (this.TW.CancellationPending) 
                return; 
            foreach (var F3 in Fake3)
            {
                if (this.TW.CancellationPending) 
                    return; 
            }
        }
    }
}

Thanks for any help!!


Solution

  • There is no way call for methodA to call methodB and let methodB return methodA (since we don't have tail recursion)

    Consider using an iterator like this. It will work in some situations where you can put try/catch in-between checkpoints.

    public void FakeBWTask()
    {
       if (this.TW.CancellationPending) 
          return; 
       foreach (object ignore in FakeBWTaskSteps())
       {
          // Other checkpoint logic here....
          if (this.TW.CancellationPending) 
              return; 
       }
    }
    
    private IEnumerable<object> FakeBWTaskSteps()
    {
       Part1();
       yield return null; // Execute checkpoint logic.
    
       Part2();
       yield return null; // Execute checkpoint logic.
    
       Part3();
       yield return null; // Execute checkpoint logic.
    
       Part4();
       yield return null; // Execute checkpoint logic.
    
       // Do some other stuff.
       yield return null; // Execute checkpoint logic.
    
       // final stuff.  No looping here.
    }