1

アプリを開発していて、非同期呼び出しで問題が発生しました...これが私がやろうとしていることです。

このアプリは JSON API を使用し、実行時にパノラマ アイテム内の ListBox に必要な値 (つまり、1 つのニュース記事) を入力します。ユーザーが ListBox アイテムを選択すると、SelectionChanged イベントが発生します。選択したアイテムから articleID を取得し、それを Update メソッドに渡して、記事の JSON 応答をダウンロードし、JSON.NET で逆シリアル化して、受信した応答から html ページをレンダリングする WebBrowser コントロールへのユーザー。

これの問題は、NavigationService を開始する前に応答を待たなければならないことですが、それを適切に行う方法がわかりません。この方法では、コードが「速すぎて」実行され、ページをレンダリングするのに間に合うように応答が得られません。

イベントコード:

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 メソッド:

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

更新方法:

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

1 に答える 1

3

非同期コールバック パターン:

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

電話:

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
于 2012-06-09T11:07:35.960 に答える