65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 5.0 和 WPF 中的 Google 图片搜索客户端

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.56/5 (5投票s)

2011年9月25日

2分钟阅读

viewsIcon

69782

downloadIcon

9553

一个简单的 50 行 C# 5.0 代码,展示了 C# 5.0 中的 await 和 async 特性。

Capture1.PNG

Capture2.PNG

引言

本文主要集中于演示 C# 5.0 中 asyncawait 关键字与 lambda 表达式结合使用如何减少代码行数以及它们的高效性。

在继续之前,让我列出先决条件。

  1. 给定的代码仅适用于 .NET 4.5。

  2. 此解决方案文件是在 Visual Studio 2011 Developer View 版本中构建的。

  3. 我使用了 Google 图片 API 来获取搜索关键词的图片 URL。
  4. 检查代理和互联网设置,因为代码使用互联网获取数据。

因此,在尝试代码之前,请确保所有内容都已就绪:)

背景

作为参考,请记住 await 关键字用于标记异步调用,因此您不再需要创建回调函数,并且可以像编写同步代码一样编写代码。编译器将为您完成所有繁重的工作。async 关键字必须出现在发出异步调用的方法的签名中。简而言之,只有方法签名中包含 async 关键字,才能使用 await 关键字。lambda 表达式也是如此。

在下面的示例中,我将展示以上所有可能性。

Using the Code

XAML 中的 UI 代码非常简单且自明。所以让我们进入核心逻辑。

程序的核心逻辑在于搜索按钮的点击事件,其中执行以下任务

任务 1:初始化 GimageSearchClient 并开始搜索。

任务 2:将四个参数传递给 beginsearch,其中第一个参数是搜索关键词以获取图片,第二个参数是要显示的搜索结果数量,第三个也是最重要的参数是 lambda 表达式,它返回 GimageSearchClient 的结果,并通过 dispatcher 将其分配给 wrapPanel。最后一个参数是 AsyncState,无论如何都是 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
        );
}

观察

这里的关键函数是通过 await DownloadImage 在上面的代码中下载图片,它再次是一个单行函数

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;
}

这里下载图片使用了 Async CTP 函数 DownloadDataTaskAsync,它以字节的形式下载图片。因此,编写了一个 byteArrayToImage 实用函数,将其转换为 BitmapImage 格式。

有趣的一点是 await 关键字,它既用于 DownloadDataTaskAsync 函数,也用于 lambda 表达式。

关注点

因此,简单来说,随着 C# 5.0 的发布,我们曾经需要编写很多页面的代码现在可以用字数来衡量,并且具有相同的功能。

© . All rights reserved.