InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Extreme threading...

This is a major upgrade for my multithreading library. If you are not familiar about what this library does, please read the other articles in this section.

New in this release are parallel operations: You can return ParallelOperation from within an asynchronous operation. The execution of the current operation will be suspended until all nested operations are executed. Additionally, a maximum number of parallel executions can be passed along, which allows you to further control the execution of the nested operations. And of course, you can select which exceptions you want to catch on each of the nested operation.

I'm primarily using these parallel operations in my InfiniTec.Exchange library to speed up lookups to Active Directory and the Exchange store. For example, when looking up members of a distribution list, I get a bunch of references, either to user in Active Directory, or references to contacts on an Exchange folder. Take a look at this method:

    1 privateIEnumerable<OperationAction> RefreshInternal(AsyncOperation baseOperation)

    2 {

    3     Dictionary<NestedOperation,EntryIdReference> operations;

    4     ExchangeStoreReference entryId;

    5     List<IAddressListEntry> result;

    6 

    7     _UnresolvableEntries = 0;

    8 

    9     yieldreturnnewNestedOperation(baseOperation, false);

   10 

   11 

   12     if (!_ResolveMembers)

   13     {

   14         _ResolveMembers = true;

   15         yieldbreak;

   16     }

   17 

   18     entryId = newExchangeStoreReference(Properties.GetProperty<byte[]>(WellknownProperties.Item.EntryId).Value);

   19 

   20     operations = newDictionary<NestedOperation, EntryIdReference>();

   21 

   22     foreach (EntryIdReference reference in DecodeMembers(entryId.StoreId))

   23     {

   24         operations.Add(

   25             newNestedOperation(reference.GetResolveOperation(BaseItem.Connection), false),

   26             reference);

   27     }

   28 

   29     yieldreturnnewParallelOperations(operations.Keys, 5);

   30 

   31     result = newList<IAddressListEntry>();

   32 

   33     foreach (KeyValuePair<NestedOperation, EntryIdReference> entry in operations)

   34     {

   35         AsyncOperation<IAddressListEntry> operation;

   36 

   37         operation = (AsyncOperation<IAddressListEntry>) entry.Key.Operation;

   38         if (operation.StatusInformation != null)

   39         {

   40             result.Add(operation.StatusInformation);

   41         }

   42         else

   43         {

   44             _UnresolvableEntries++;

   45         }

   46     }

   47 

   48     _Members = result.AsReadOnly();

   49 }

In Line 9, I call the original refresh method, using the NestedOperation operation action. After that, I decode those member entries in lines 22 to 27 and put them in a dictionary. The interesting thing happens in line 29. At this point, I return a ParallelOperation operation action with a list of those member references. Additionally, a maximum number of concurrent operations of 5 is specified.

When the method resumes it's operation in line 31, all nested operations have been completed.

Changelog

  • Introduced parallel operations: Using the ParallelOperations action, you can now return multiple nested operations which will be executed in parallel. Once all nested operations are finished, the parent operation is resumed.
  • The AsyncOperation<StatusType> can now also be used to return a result. Just return an OperationResult<StatusType> in the enumerator.
  • Fixed a bug with nested operations and exception handling

Downloads

InfiniTec.Threading.zip (268,722 Bytes)
Version 2.5. Includes source, binaries and documentation

Technorati:

Posted by Henning Krause on Saturday, January 27, 2007 12:00 AM, last modified on Monday, November 29, 2010 8:27 PM
Permalink | Post RSSRSS comment feed