且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Windows Phone 7的 - 等待Web客户端完成

更新时间:2023-09-21 11:32:40

异步回调格局:

 公共无效更新(动作回调,动作<异常和GT;错误)
{
    webClient.DownloadStringCompleted + =(P,Q)=>
    {
        如果(q.Error == NULL)
        {
            // 做一点事
            回电话();
        }
        其他
        {
            错误(q.Error);
        }
    };
    webClient.DownloadStringAsync(新的URI(jsonUri));
}

电话:

  App.Current.JsonModel.Update(()=>
{
    //异步完成后执行
    NavigationService.Navigate(新的URI(?/ View.xaml ID =+ item.Id,UriKind.Relative));
},
(错误)=>
{
    //错误处理
});
//略高于异步调用后执行

I'm developing an app and have run into a problem with asynchronous calls... Here's what i'm trying to do.

The app consumes a JSON API, and, when run, fills the ListBox within a panorama item with the necessary values (i.e. a single news article). When a user selects a ListBox item, the SelectionChanged event is fired - it picks up the articleID from the selected item, and passes it to an Update method to download the JSON response for the article, deserialize it with JSON.NET, and taking the user to the WebBrowser control which renders a html page from the response received.

The problem with this is that I have to wait for the response before I start the NavigationService, but I'm not sure how to do that properly. This way, the code runs "too fast" and I don't get my response in time to render the page.

The event code:

private void lstNews_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (lstNews.SelectedIndex == -1)
        {
            return;
        }

        ShowArticle _article = new ShowArticle();
        ListBox lb = (ListBox)sender;
        GetArticles item = (GetArticles)lb.SelectedItem;
        string passId = ApiRepository.ApiEndpoints.GetArticleResponseByID(item.Id);
        App.Current.JsonModel.JsonUri = passId;
        App.Current.JsonModel.Update();

        lstNews.SelectedIndex = -1;

        NavigationService.Navigate(new Uri("/View.xaml?id=" + item.Id, UriKind.Relative));
    }

OnNavigatedTo method in the View:

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {          
        base.OnNavigatedTo(e);

        long sentString = long.Parse(NavigationContext.QueryString["id"]);

        string articleUri = ApiRepository.ApiEndpoints.GetArticleResponseByID(Convert.ToInt32(sentString));

        //this throws an error, runs "too fast"
        _article = App.Current.JsonModel.ArticleItems[0];
    }

The update method:

    public void Update()
    {
        ShowArticle article = new ShowArticle();

        try
        {
            webClient.DownloadStringCompleted += (p, q) =>
            {
                if (q.Error == null)
                {
                    var deserialized = JsonConvert.DeserializeObject<ShowArticle>(q.Result);
                    _articleItems.Clear();
                    _articleItems.Add(deserialized);
                }
            };
        }

        catch (Exception ex)
        { 
            //ignore this
        }

        webClient.DownloadStringAsync(new Uri(jsonUri));
    }

async callback pattern:

public void Update(Action callback, Action<Exception> error)
{
    webClient.DownloadStringCompleted += (p, q) =>
    {
        if (q.Error == null)
        {
            // do something
            callback();               
        }
        else
        {
            error(q.Error);
        }
    };
    webClient.DownloadStringAsync(new Uri(jsonUri));
}

call:

App.Current.JsonModel.Update(() =>
{
    // executes after async completion
    NavigationService.Navigate(new Uri("/View.xaml?id=" + item.Id, UriKind.Relative));
},
(error) =>
{
    // error handling
});
// executes just after async call above