Print Page | Close Window

AddAsyncQuery Question

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2009
Forum Discription: For .NET 3.5
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=1391
Printed Date: 25-Mar-2025 at 10:42am


Topic: AddAsyncQuery Question
Posted By: skingaby
Subject: AddAsyncQuery Question
Date Posted: 24-Jul-2009 at 8:01am
I have these methods that initialize my server side Entity Manager cache:
private static IList<IEntityQuery> GetInitializationQueries()

{
     var queries = new List<IEntityQuery>();
     queries.Add(_defaultManager.AccountingMonths);
     queries.Add(_defaultManager.DealTypes);
     return queries;
}
public static void InitializeCache()
{
     var queries = GetInitializationQueries();
     foreach (var item in queries)
     {
          _defaultManager.ExecuteQuery(item);
     }
}


I am trying to write an AsyncParallelTask to do the same thing for the client, and I can get this to work:
public static void InitializeCacheAsync(Action<AsyncParallelTaskCompletedArgs> callback)

{
     var task = AsyncParallelTask.Create();
     task.AddExceptionHandler(InitializationExceptionHandler);
     AddInitializationQueries(task);
     task.Execute(callback);
}
private static void AddInitializationQueries(AsyncParallelTask<object> task)
{
     task.AddAsyncQuery(1, x => _defaultManager.AccountingMonths);
     task.AddAsyncQuery(2, x => _defaultManager.DealTypes);
}


I would like to do this instead:
private static void AddInitializationQueries(AsyncParallelTask<object> task)

{
     var queries = GetInitializationQueries();
     int i = 1;
     foreach (var item in queries)
     {
          task.AddAsyncQuery(i, x => item);
          i++;
     }
}


But the AddAsyncQuery method needs an IEntityQuery<T> but I only have IEntityQuery objects in my collection. Is there any way to work around this? Thanks, Simon



Replies:
Posted By: kimj
Date Posted: 24-Jul-2009 at 10:55am
Yes, there is a workaround.  The extension methods, like AddAsyncQuery, are there to help hide some of the complexities of the syntax, but aren't required.  Here's how you can do this using AddAsyncAction instead:
 

      foreach (var item in queries) {
        task.AddAsyncAction<EntityFetchedEventArgs>(i,
          (args, callback) => _defaultManager.ExecuteQueryAsync(item, callback, null),
          null);
        i++;
      }


Posted By: skingaby
Date Posted: 29-Jul-2009 at 7:45am
I'm not getting any errors with this code, but it does not seem to be loading the entities into the cache. My unit tests are getting the Null entity instead. Any suggestions? Thanks, Simon


Posted By: kimj
Date Posted: 29-Jul-2009 at 8:33am
Hmm, I'd check the completion action on the AsyncParallelTask to see what it contains, since it will have results from all actions in the task.  I'd also check that the EntityManager used for all queries is the correct one.  Also check to see if an error was caught by your exception handler.  And since it's a test method, make sure it's not exiting prematurely. 


Posted By: skingaby
Date Posted: 29-Jul-2009 at 1:06pm
Thanks. I've stepped through it now and it does not seem to be erroring anywhere. The completionmap is showing all 6 queries executed and completed with no errors. I have added errorhandlers to the tasks. Nothing seems to be failing, however, when I use this syntax, the cached entities are available:
public static void InitializeCacheAsync(AsyncCompletedCallback<AsyncEventArgs> serialCallback, Action<AsyncParallelTaskCompletedArgs> completionAction)

{
     var task = AsyncParallelTask.Create();
     task.AddExceptionHandler(InitializationExceptionHandler);
     AddInitializationQueries(task);
     task.Execute(serialCallback, completionAction);
}

private static void AddInitializationQueries(AsyncParallelTask<object> task)
{
     task.AddAsyncQuery(1, x => _defaultManager.AccountingMonths);
     task.AddAsyncQuery(2, x => _defaultManager.DealTypes);
}


When I execute this code, the entities are not available:
public static void InitializeCacheAsync(AsyncCompletedCallback<AsyncEventArgs> serialCallback, Action<AsyncParallelTaskCompletedArgs> completionAction)

{
     var task = AsyncParallelTask.Create();
     task.AddExceptionHandler(InitializationExceptionHandler);
     AddInitializationQueries(task);
     task.Execute(serialCallback, completionAction);
}

private static void AddInitializationQueries(AsyncParallelTask<object> task)
{
     var queries = GetInitializationQueries();
     int i = 1;
     foreach (var item in queries)
     {
          //task.AddAsyncQuery(i, x => item);
          task.AddAsyncAction<EntityFetchedEventArgs>(i,
               (args, callback) =>
               _defaultManager.ExecuteQueryAsync(item, callback, null),
               null);
          i++;
     }
}
          
private static IList<IEntityQuery> GetInitializationQueries()
{
     var queries = new List<IEntityQuery>();
     queries.Add(_defaultManager.AccountingMonths);
     queries.Add(_defaultManager.DealTypes);
     return queries;
}


Is the problem in making creating the list of queries as an IList<IEntityQuery>? Should it be IList<IUntypedEntityQuery>?


Posted By: kimj
Date Posted: 29-Jul-2009 at 4:36pm
Ah, it's a problem with closures within the loop adding the tasks.  Use this instead -

      foreach (var item in queries) {
        IEntityQuery query = item;
        task.AddAsyncAction<EntityFetchedEventArgs>(i,
          (args, callback) => _defaultManager.ExecuteQueryAsync(query, callback, null),
          null);
        i++;
      }


Posted By: skingaby
Date Posted: 30-Jul-2009 at 6:45am
That fixed it! Thanks!



Print Page | Close Window