LA.NET [EN]

Jun 18

Today we’re going to improve the code we’ve started writing yesterday: we’re adding canceling support. As you might recall, in our last post we’ve built a simple class which supports a single asynchronous operation at a time. Since we only support one asynchronous operation at a time and we can only start one asynchronous operation from our class, then we only need to add a parameterless CancelAsync method.

Here’s how you might implement the CancelAsync method:

public void CancelAsync() {
    if (!_isRunning) {
       return;
    }
    _cancelOperation = true;
}

As you can see, we need to add a _cancel operation field which is used for notifying the helper method that runs in asynchronous mode that it should stop. This means that we need to change our asynchronous method slightly so that it checks that value in the for cycle and passes that value for the PrimeNumberVerificationCompletedEventArgs instance passed to whoever consumes the PrimeNumberCompleted event. Since I’ve cheated a little bit in the previous post, we’ve already got the hooking points for flowing the needed information. This means that changes are mostly concentrated on the IsPrimeAsync method:

public void IsPrimeAsync(Int32 number) {
  if (_isRunning) {
      throw new InvalidOperationException();
  }
  _isRunning = true;
  _currentOperation = AsyncOperationManager.CreateOperation(null);
  ThreadPool.QueueUserWorkItem(state =>
                  {
                      var numberToCheck = (Int32)number;
                      var isPrime = false;
                      Exception throwException = null;
                      try {
                          if (number > 2) {
                              isPrime = true;
                              var half = number / 2;
                              for (var i = 2; i < half && !_cancelOperation; i++) {
                                  if (number % i == 0) {
                                      isPrime = false;
                                      break;
                                  }
                              }                               
                          }
                      }
                      catch (Exception ex) {
                          throwException = ex;
                      }
                      finally {
                          NotifyEndOfOperation(numberToCheck,
                                               isPrime,
                                               _cancelOperation,
                                               throwException);
                      }

                  }, number);
}

There’s still one thing missing: we need to clean up the _cancelOperation flag when that asynchronous operation ends. This can be done from within the anonymous method we’re using inside the NotifyEndOfOperation method:

private void NotifyEndOfOperation( Int32 numberToTest,
  Boolean isPrime,
  Boolean cancelled,
  Exception thrownException ){
      var evt = new PrimeNumberVerificationCompletedEventArgs(
                  numberToTest,
                  isPrime,
                  thrownException,
                  cancelled,
                  null);
      _currentOperation.PostOperationCompleted(
          state => {
                      _isRunning = false;
                      _cancelOperation = false;
                      OnPrimeNumberCompleted((PrimeNumberVerificationCompletedEventArgs)state);
                   },
                  evt);
}

And that’s it. As you can see, supporting cancelation is not really that hard. We’ll keep improving this sample and on the next post we’ll see how we can improve our code so that it supports multiple asynchronous operations. Keep tuned.

1 comment so far

  1. buy 1 cialis
    1:56 am - 8-3-2009

    WLz2kR Perfect work!

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>