Select to view content in your preferred language

2 queries and an intersect, one button click?

576
2
Jump to solution
06-20-2012 03:55 PM
TanyaOwens
Occasional Contributor III
Currently I have 2 queries that run off their own button and an intersection of those two queries running on a separate button click. Is there a way to set up the intersection to run after the two queries on a single button click?
0 Kudos
1 Solution

Accepted Solutions
TanyaOwens
Occasional Contributor III
I got a different code from Akshat Nag on a different forum and it worked like a dream. I thought I would share:
// create a bool array at global scope:  bool[] completedArr = new bool[2];  // on completed of 1st qry write:  completedArr [0]=true;  if(completedArr [0]==true && completedArr [1]==true)  {  // call a function/write code to merge and display the result  MERGE_RESULT();  }  // on completin of qry 2 write following  completedArr [1]=true;  if(completedArr [0] ==true && completedArr [1]==true)  {  MERGE_RESULT();  }  // in merge method write like this :  private void MERGE_RESULT()  {  completedArr [0]=false;  completedArr [1]=false;  // your logic to merge the results  }

View solution in original post

0 Kudos
2 Replies
JoeHershman
MVP Regular Contributor
Yes it is possible, it is certainly not simple and requires understanding how asynchronous calls work.  What I would do (not saying that is the best way) is setup some timers to run things and help synch up at the end.  Something along these lines (this code is in no way tested, just an idea of an approach)




        FeatureSet[] _featureSet = new FeatureSet[2];
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Query query1 = new Query();
            Query query2 = new Query();
            QueryTask queryTask = new QueryTask();
            queryTask.ExecuteCompleted += QueryCompleted;
            // Setup your querys


            DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500)};


            timer.Tick += (s, arg) =>
                              {
                                  if ( queryTask.IsBusy ) return;


                                  timer.Stop();
                                  queryTask.ExecuteAsync(query2, "QUERY2");
                              };


            queryTask.ExecuteAsync(query1, "QUERY1");
            timer.Start();
        }


        private void QueryCompleted(object sender, QueryEventArgs e)
        {
            if ( (string)e.UserState == "QUERY1")
            {
                _featureSet[0] = e.FeatureSet;
            }
            if ( (string)e.UserState == "QUERY2" )
            {
                _featureSet[1] = e.FeatureSet;
            }


            DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) };


            timer.Tick += (s, arg) =>
                              {
                                  if ( _featureSet[0] == null || _featureSet[1] == null ) return;


                                  timer.Stop();
                                  //do the create intersection stuff
                                  //make sure to reset _featureSet[] when done with FeatureSet[] _featureSet = new FeatureSet[2];
                              };


            timer.Start();
        }





What a DispatcherTimer does is run the .Tick handler over and over until Stop() is called, but will wait between each time it calls the event handler, the pause amount is the Interval property.  DispatcherTimer is nice for this purpose because it runs on the primary thread, so no need to synch threads when it is used.

In the button click event handler the Tick method checks if the QueryTask is busy every 1/2 second.  Once it is no longer busy it runs the second query.  When the Queries are run the userToken variable is included in the Execute call so in the Complete handler it can be determined which query result it is.

The Timer in the Execute handler keeps checking if both of the queries are done, and once they are it moves onto executing the code that uses the intersction.

Again there are different ways this could be accomplished, this is just the general approach I would take

Hope that helps
Thanks,
-Joe
0 Kudos
TanyaOwens
Occasional Contributor III
I got a different code from Akshat Nag on a different forum and it worked like a dream. I thought I would share:
// create a bool array at global scope:  bool[] completedArr = new bool[2];  // on completed of 1st qry write:  completedArr [0]=true;  if(completedArr [0]==true && completedArr [1]==true)  {  // call a function/write code to merge and display the result  MERGE_RESULT();  }  // on completin of qry 2 write following  completedArr [1]=true;  if(completedArr [0] ==true && completedArr [1]==true)  {  MERGE_RESULT();  }  // in merge method write like this :  private void MERGE_RESULT()  {  completedArr [0]=false;  completedArr [1]=false;  // your logic to merge the results  }
0 Kudos