Await阻止UI线程,网络相关

时间:2013-01-25 17:04:35

标签: c# .net windows-8 windows-runtime async-await

我在Windows应用商店应用中有这段代码,我点击按钮。但不知何故,当我在极少数情况下单击此按钮时,UI会冻结。它主要发生在我连接到比我通常连接的Wi-Fi网络更远的Wi-Fi网络时。考虑到我从互联网上下载RSS源,很可能与我使用async / await关键字有关。如果我正确理解了async / await的机制,那么UI线程根本就不应该阻塞。我在这里错过了什么吗?

    private async void Add_Click(object sender, RoutedEventArgs e)
    {
        AddButton.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        DownloadProgressRing.Visibility = Windows.UI.Xaml.Visibility.Visible;
        DownloadProgressRing.IsActive = true;

        RssData rssData = App.Current.Resources["rssData"] as RssData;
        Uri uri = FixUrl(RssUrl.Text);

        if (uri != null)
        {
            newRssFeed = new RssFeed(uri.ToString());
            Task<bool> success = newRssFeed.RetrieveFeed();
            if (await success)
            {
                SubmitButtonPanel.Visibility = Windows.UI.Xaml.Visibility.Visible;
                FeedTitleTextBox.Text = newRssFeed.Title == null ? String.Empty : newRssFeed.Title;
            }
        }
    }

RssFeed的构造函数:

    public RssFeed(string url)
    {
        Url = url; 
    }

RetrieveFeed函数:

    public async Task<bool> RetrieveFeed()
    {
        if (Url != null)
        {
            try
            {
                SyndicationClient sc = new SyndicationClient();
                SyndicationFeed sf = await sc.RetrieveFeedAsync(new Uri(Url, UriKind.Absolute));
                if (sf != null)
                {
                    ValidateAndInitFeed(sf);
                    return true;
                }
            }
            catch (Exception ex)
            {
            }
        }

        return false;
    }

    private void ValidateAndInitFeed(SyndicationFeed feed)
    {
        if (feed.Title != null)
            Title = feed.Title.Text;
        if (feed.ImageUri != null)
            Image = feed.ImageUri.ToString();
        if (feed.Subtitle != null)
            Subtitle = feed.Subtitle.Text;
    }

3 个答案:

答案 0 :(得分:2)

尝试在后台线程上调用RetrieveFeed()。也许处理请求或响应是需要花费大量时间的,如果它是在UI线程上启动的 - 它将在UI线程上运行。

Task<bool> success = null;
await Task.Run(
    () => success = newRssFeed.RetrieveFeed());

答案 1 :(得分:0)

使用async / await看起来没问题。你引用了一个遥远的Wi-Fi连接,这可能纯粹是一个弱信号,因此带宽很差。

我希望这会有所帮助。

答案 2 :(得分:0)

我在一些Windows Phone应用程序上遇到了同样的问题,我没有任何好的解释,唯一的好处就是Killercam提到的那个。

当你调用异步方法时,它不会立即返回(我假设方法不像return Task.Factory.StartNew(...);),它做了一些工作,设置回调然后返回,如果工作它make具有与网络连接相关的任何内容,在缓慢的连接中,这可以阻止该功能。

测试此症状的一个好方法是连接到具有wifi的路由器,然后断开路由器与互联网的连接,您将具有与您描述的相同的行为。