Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Google Image Search Client in C# 5.0 and WPF

0.00/5 (No votes)
25 Sep 2011 1  
A simple 50 lines of C# 5.0 code which showcases the await and async features in C# 5.0.

Capture1.PNG

Capture2.PNG

Introduction

This article mainly focuses on demonstrating how the async and await keywords combined with lambda expressions in C# 5.0 are going to minimize the lines of code and how efficient they are.

Before going further, let me list the prerequisites.

  1. The given code works only with .NET 4.5.

  2. This solution file was built in Visual Studio 2011 Developer View version.

  3. I used Google Image API for getting image URLs of the search keyword.
  4. Check for proxy and internet settings since the code uses internet to get the data.

Hence get all the things in place before trying out the code :)

Background

For reference, remember that the await keyword is used to mark asynchronous calls so that you don’t need to create callback functions anymore and can write code in the same way as if it were synchronous. The compiler will do all of the heavy lifting for you. The async keyword must be presented in the signature of the method that makes the asynchronous calls. Briefly, you can use the await keyword only if the async keyword is in the method signature. The same is true for lambda expressions.

In the below example, I am going to show all the above said possibilities.

Using the Code

The UI code in XAML is quite simple and very much self explanatory. So let us go for the core logic.

The core logic of the program rests with the search button click where in the following tasks are performed:

Task 1: Initialize GimageSearchClient and begin search.

Task 2: Pass four parameters to beginsearch such that the first among them is the search keyword to get images, the second one is the number of results to display, the third and very important one is the lambda expression which returns the results of GimageSearchClient and assigns the same to wrapPanel through a dispatcher. The final param is the AsyncState which is any way null.

 private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
    wrapPanel.Children.Clear();
    GimageSearchClient client = new GimageSearchClient("http://www.google.com");
    IList<IImageResult> results ;
   
     IAsyncResult result= client.BeginSearch(
        textSearch.Text.Trim(),  //param1
        int.Parse(textResult.Text), //param2
        ((arResult) => //param3
        {
            results = client.EndSearch(arResult);
            Dispatcher.Invoke(DispatcherPriority.Send,
                (Action<IList<IImageResult>>)(async (data) =>
                 { 
                      for (int i = 0; i < results.Count; i++)
                        {
                            Image img = new Image{
                            Source = await DownloadImage(results[i].TbImage.Url),
                             Stretch = Stretch.UniformToFill,
                             StretchDirection = StretchDirection.DownOnly,
                                };
                            wrapPanel.Children.Add(img);
                        }
            }),null);
        }),
        null //param4
        );
}

Observation

The key function here is to download the image which is done by await DownloadImage in the above code which is again a single line function:

private async Task<BitmapImage> DownloadImage(string url)
{
    return byteArrayToImage(await new WebClient().DownloadDataTaskAsync(url));
}

public BitmapImage byteArrayToImage(byte[] byteArrayIn)
{
    BitmapImage myBitmapImage;
    using (MemoryStream stream = new MemoryStream(byteArrayIn))
    {
        myBitmapImage = new BitmapImage();
        myBitmapImage.BeginInit();
        myBitmapImage.StreamSource = stream;
        myBitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        myBitmapImage.EndInit();
    }
    return myBitmapImage;
}

Here the download image uses the Async CTP function DownloadDataTaskAsync which downloads the image in terms of bytes. Hence a byteArrayToImage utility function is written to convert the same in BitmapImage format.

The interesting point here is the await keyword, which is used both for the DownloadDataTaskAsync function and the lambda expression used.

Points of Interest

Hence to be simple, with C# 5.0 coming out, the code for which once we used to write pages and pages is going to be in word count, with the same functionality.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here