Multithreading: adding cancelation to the initial event based pattern implementation

Published Thu, Jun 18 2009 22:45

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.

Filed under: ,

Comments

# 9eFish said on Thursday, June 18, 2009 9:07 PM

9efish.感谢你的文章 - Trackback from 9eFish

# LA.NET [EN] said on Saturday, June 20, 2009 7:06 AM

I know that I’ve said that the next post of the series would be on how to support several asynchronous

# ASPInsiders said on Saturday, June 20, 2009 7:24 AM

I know that I’ve said that the next post of the series would be on how to support several asynchronous

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above:  

Search

This Blog

Tags

Community

Archives

Syndication

Email Notifications

News




  • View Luis Abreu's profile on LinkedIn


    Follow me at Twitter

    My books

    Silverlight 4.0: Curso Completo

    ASP.NET 4.0: Curso Completo

    Portuguese LINQ book cover

    Portuguese ASP.NET 3.5 book cover

    Portuguese ASP.NET AJAX book cover

    Portuguese ASP.NET AJAX book cover