I have noticed the unstable behavior when I try to work with queries asynchronously.
When I start a new query before the completion of the previous one the application does not show stable behavior (sometimes it crashes and sometimes not). But If I start the new query after the completion of the previous one the application is then stable.
Please find below the part of code where I pointed out when the problem occurs and when not. The first query is here the employees from the Northwind database and the queries that should be executed after the first one are put into the method called "then_multiple_async_anonymous_queries_work".
This code comes from a small example project I have made to illustrate this problem. You can get it from me of course if you want to run it. Any comments/ideas about this problem are welcome.
//Module: BusinessApplicationModule //file: BusinessApplicationModuleViewModel.cs
private NorthwindIBEntities _mgr = new NorthwindIBEntities();
*****************************************************
//ViewModel constructor: public BusinessApplicationModuleViewModel() { .......
var query = _mgr.Employees; var op = query.ExecuteAsync(); op.Completed += (s, args) => { if (args.Error == null) { args.Results.ForEach(Employees.Add); CurrentEmployee = Employees.FirstOrDefault(); RaisePropertyChanged("CurrentEmployee"); //Consider moving into the property //then_multiple_async_anonymous_queries_work(); ///works well } else { throw new InvalidOperationException( "Server error during query: " + args.Error.Message); } };
then_multiple_async_anonymous_queries_work(); //unstable behaviour
} ***********************************************************
public void then_multiple_async_anonymous_queries_work() {
var fetchCount = 0; _mgr.Fetching += delegate { fetchCount++; }; const int iterations = 100; int countDownCounter = iterations;
var locker = new Object();
Action<BaseOperation, IEnumerable> countDown = (op, results) => { LogFetchingData.Add("In callback for " + op.UserState); lock (locker) { countDownCounter--; if (0 >= countDownCounter) { LogFetchingData.Add("*** Fetch Count = " + fetchCount);
} } };
for (var i = 0; i < iterations; i++) { _mgr.Employees.Select(emp => new { emp.EmployeeID, emp.Orders.Count }) .With(QueryStrategy.DataSourceOnly) .ExecuteAsync(op => countDown((BaseOperation)op, (op.HasError) ? null : (IEnumerable)op.Results), i); } }
|