Concurrent calls using SearchAsync() of BingSearchProvider

3 posts, 1 answers
  1. Senthil Subramanian
    Senthil Subramanian avatar
    10 posts
    Member since:
    Jun 2010

    Posted 17 Nov 2010 Link to this post

    Hi,

        When using the SearchAsync() of BingSearchProvider for concurrent calls I'm facing a problem where in the responses for all the calls has the same result location and user data. This is the code that I'm using to make the call.
        

    if

     

     

    (searchProvider != null)

     

    {

     

     

    SearchRequest request = new SearchRequest();

     

     

    request.Culture =

     

    CultureInfo.CurrentCulture;

     

    request.Query = address;

    request.UserData = userData

     

    as object;

     

     

     

    this.searchProvider.SearchCompleted += new EventHandler<SearchCompletedEventArgs>(searchProvider_SearchCompleted);

     

     

     

    this.searchProvider.SearchAsync(request);

     

    }

    The above part will be called multiple times even before the previous SearchAsync() function returned a result.

     

     

     

     

    void searchProvider_SearchCompleted(object sender, SearchCompletedEventArgs e)

     

    {

     

     

    SearchResponse response = e.Response;

     

    Location

     

     

    locn = new Location();

     

     

     

     

     

     


    if
    (response.ResultSets[0].Results.Count > 0)

     

    {

     

     

    foreach (SearchResultBase result in response.ResultSets[0].Results)

     

    {

    locn = result.LocationData.Locations[0];

    }

    }

     

     

    if (response.ResultSets[0].SearchRegion != null)

     

    {

     

     

    if (response.ResultSets[0].SearchRegion.GeocodeLocation.Address != null

     

     

     

     

     

    && response.ResultSets[0].SearchRegion.GeocodeLocation.Locations.Count > 0)

    {

    locn = response.ResultSets[0].SearchRegion.GeocodeLocation.Locations.First();

    locn.Description = address;

    }

    }

    }

     

    MessageBox

     

     

    .Show("RequestUserData : " + e.Response.RequestUserData.ToString() + "\nLocation : " + locn.Latitude + "," + locn.Longitude);

     

    }
        
    Is there any thing that I'm missing out in this? Please help me overcome this problem.

    I'm using Telerik RadControls for Silverlight 4 Version 2010_2_0924. 

    Thanks in Advance,
    Senthil
  2. Answer
    Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 19 Nov 2010 Link to this post

    Hi Senthil Subramanian,

    I am afraid I was not able to reproduce the problem. I've created a small solution which works as follows: select query string from the list randomly, create custom user data, show request parameters in the list box and send request. When the response comes, it is processed in the same way you do and show response parameters in the list box. Sending request is set on timer tick with quite small interval 0.5 sec. So 3 requests can be sent before first response comes. As expected response contains user data from the correspondent request (different for different requests) and location which corresponds to the query string. You can find my code below:

    <UserControl x:Class="MultipleSearchRequests.MainPage"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 mc:Ignorable="d"
                 d:DesignHeight="500" d:DesignWidth="700">
      
        <Grid x:Name="LayoutRoot" Background="White">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
              
            <telerik:RadMap x:Name="radMap" 
                            Center="0,0"
                            ZoomLevel="2">
                <telerik:RadMap.Provider>
                    <telerik:OpenStreetMapProvider />
                </telerik:RadMap.Provider>
                <telerik:InformationLayer x:Name="informationLayer">
                </telerik:InformationLayer>
            </telerik:RadMap>
      
            <Grid Grid.Column="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Button Click="DoAction">
                    <TextBlock Text="Do Action" />
                </Button>
                  
                <ListBox Name="userData" Grid.Row="1">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="Auto" />
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
      
                                <TextBlock Grid.Row="0" Grid.Column="0" Text="Action:" />
                                <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Action}" />
      
                                <TextBlock Grid.Row="1" Grid.Column="0" Text="Req. number:" />
                                <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=UserData.Number}" />
      
                                <TextBlock Grid.Row="2" Grid.Column="0" Text="Random data:" />
                                <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=UserData.RandomData}" />
      
                                <TextBlock Grid.Row="3" Grid.Column="0" Text="{Binding Path=Label}" />
                                <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding Path=LocationFound}" />
                            </Grid>                     
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Grid>
      
        </Grid>
    </UserControl>

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Threading;
    using Telerik.Windows.Controls.Map;
      
    namespace MultipleSearchRequests
    {
        public partial class MainPage : UserControl
        {
            private Random rnd = new Random();
            private BingSearchProvider searchProvider;
            private DispatcherTimer timer = new DispatcherTimer();
            private int requestCount = 0;
      
            private readonly string[] requests = new string[]
            {
                "Restaurants in Honolulu",
                "Chinese restaurants in San Francisco",
                "Eiffel Tower, Paris",
                "Kremlin, Moscow"
            };
      
            public MainPage()
            {
                InitializeComponent();
      
                this.searchProvider = new BingSearchProvider();
                this.searchProvider.ApplicationId = "Your_BING_ID";
                this.searchProvider.MapControl = this.radMap;
                this.searchProvider.SearchCompleted += new EventHandler<SearchCompletedEventArgs>(this.Provider_SearchCompleted);
      
                this.timer.Interval = TimeSpan.FromSeconds(0.5);
                this.timer.Tick += new EventHandler(this.SendRequest);
            }
      
            private void SendRequest(object e, EventArgs args)
            {
                string query = requests[rnd.Next(requests.Length - 1)];
      
                RequestUserData userData = new RequestUserData()
                {
                    Number = this.requestCount,
                    RandomData = rnd.NextDouble()
                };
      
                // Show request data in the list box
                ListItemData item = new ListItemData()
                {
                    Action = "Send",
                    UserData = userData,
                    Label = "Search:",
                    LocationFound = query
                };
                this.userData.Items.Add(item);
      
                // Send request
                SearchRequest request = new SearchRequest();
                request.Culture = new System.Globalization.CultureInfo("en-US");
                request.Query = query;
                request.UserData = userData;
      
                this.searchProvider.SearchAsync(request);
      
                this.requestCount++;
            }
      
            private void Provider_SearchCompleted(object sender, SearchCompletedEventArgs args)
            {
                SearchResponse response = args.Response;
      
                Location locn = Location.Empty; 
                if (response.ResultSets[0].Results.Count > 0)  
                
                    SearchResultBase result = response.ResultSets[0].Results[0]; 
                    locn = result.LocationData.Locations[0]; 
                
      
                if (response.ResultSets[0].SearchRegion != null)  
                
                    if (response.ResultSets[0].SearchRegion.GeocodeLocation.Address != null && response.ResultSets[0].SearchRegion.GeocodeLocation.Locations.Count > 0) 
                    
                        locn = response.ResultSets[0].SearchRegion.GeocodeLocation.Locations.First(); 
                    
                }
      
                if (!locn.IsEmpty)
                {
                    this.informationLayer.Items.Clear();
                    this.informationLayer.Items.Add(locn);
      
                    RequestUserData userData = args.Response.RequestUserData as RequestUserData;
      
                    // Show responcs data in the list box
                    ListItemData item = new ListItemData()
                    {
                        Action = "Recieve",
                        UserData = userData,
                        Label = "Location found:",
                        LocationFound = locn.ToString()
                    };
                    this.userData.Items.Add(item);
                }
            }
      
            private void DoAction(object sender, RoutedEventArgs e)
            {
                if (timer.IsEnabled)
                {
                    this.timer.Stop();
                }
                else
                {
                    this.timer.Start();
                }
            }
      
            /// <summary>
            /// Custom user data to send withing request
            /// </summary>
            public class RequestUserData
            {
                public int Number
                {
                    get;
                    set;
                }
      
                public double RandomData
                {
                    get;
                    set;
                }
            }
      
            /// <summary>
            /// Data to show in the ListBox
            /// </summary>
            public class ListItemData
            {
                public string Action
                {
                    get;
                    set;
                }
      
                public string Label
                {
                    get;
                    set;
                }
      
                public RequestUserData UserData
                {
                    get;
                    set;
                }
      
                public string LocationFound
                {
                    get;
                    set;
                }
            }
      
        }
    }


    Greetings,
    Andrey Murzov
    the Telerik team
    Browse the videos here>> to help you get started with RadControls for Silverlight
  3. DevCraft banner
  4. Senthil Subramanian
    Senthil Subramanian avatar
    10 posts
    Member since:
    Jun 2010

    Posted 19 Nov 2010 Link to this post

    The problem with my code was that I was creating a new event handler function for every SearchAsync() function. It worked after I created a single event handler and then called the SearchAsync() multiple times.

    Thanks for ur reply,
    Senthil.
Back to Top