Windows Phone 7: проблема веб-службы - PullRequest
0 голосов
/ 05 сентября 2010

Из приложения WindowsPhone7 мне нужно запросить веб-сервис, отправив строковый параметр "category", ожидающий получить строку взамен.Я пытался идентично следовать примеру «Прогноз погоды» из MSDN, но всегда получаю пустую строку.Если я добавлю несколько команд Debug.WriteLine, то увижу, что обратный вызов выполняется ПОСЛЕ того, как возвращается ответ, то есть: возврат не ожидает завершения асинхронной операции.

ИМХО, я уважал пример кода100%, кто-нибудь может увидеть, где что-то идет не так?Код ниже, спасибо за ваше время:

    public partial class MainPage : PhoneApplicationPage
{
    // Constructor
    public MainPage()
    {
        InitializeComponent();
    }

    /// <summary>
    /// Event handler to handle when this page is navigated to
    /// </summary>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        SearchService searchService = new SearchService();
        searchService.GetCategoryCounter("pizza")
        Globals.pizzaCounter = searchService.Counter;    

        searchService.GetCategoryCounter("pasta")
        Globals.pastaCounter = searchService.Counter;

        pizzacounter.Text = Globals.pizzaCounter;
        pastacounter.Text = Globals.pastaCounter;
    }
}

.

public class SearchService
{

    #region member variables
    private string currentCategoryCount = "";
    public event PropertyChangedEventHandler PropertyChanged;

    #endregion member variables

    #region accessors
    public String Counter
    {
        get
        {
            return currentCategoryCount;
        }
        set
        {
            if (value != currentCategoryCount)
            {
                currentCategoryCount = value;
                NotifyPropertyChanged("Counter");
            }
        }
    }
    #endregion accessors

    #region private Helpers

    /// <summary>
    /// Raise the PropertyChanged event and pass along the property that changed
    /// </summary>
    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    #endregion private Helpers


    /*
    * GetCategoryCounter Method:
    * 
    * @param category
    *            : the category whose counter is to be retrieved
    */
    public void GetCategoryCounter(string category)
    {
        try
        {
            // form the URI
            UriBuilder fullUri = new UriBuilder("http://www.mywebsite.com/items/stats");
            fullUri.Query = "category=" + category;

            // initialize a new WebRequest
            HttpWebRequest counterRequest = (HttpWebRequest)WebRequest.Create(fullUri.Uri);

            // set up the state object for the async request
            CounterUpdateState counterState = new CounterUpdateState();
            counterState.AsyncRequest = counterRequest;

            // start the asynchronous request
            counterRequest.BeginGetResponse(new AsyncCallback(HandleCounterResponse), counterState);
            return;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// Handle the information returned from the async request
    /// </summary>
    /// <param name="asyncResult"></param>
    private void HandleCounterResponse(IAsyncResult asyncResult)
    {
        // get the state information
        CounterUpdateState counterState = (CounterUpdateState)asyncResult.AsyncState;
        HttpWebRequest counterRequest = (HttpWebRequest)counterState.AsyncRequest;

        // end the async request
        counterState.AsyncResponse = (HttpWebResponse)counterRequest.EndGetResponse(asyncResult);

        Stream streamResult;
        string currentCount = "";

        try
        {
            // get the stream containing the response from the async call
            streamResult = counterState.AsyncResponse.GetResponseStream();

            StreamReader reader = new StreamReader(streamResult);
            currentCount = reader.ReadToEnd();

            // copy the data over
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                Counter = currentCount;
            });
        }
        catch (FormatException ex)
        {
            throw ex;
        }

    }
}

/// <summary>
/// State information for our BeginGetResponse async call
/// </summary>
public class CounterUpdateState
{
    public HttpWebRequest AsyncRequest { get; set; }
    public HttpWebResponse AsyncResponse { get; set; }
}

1 Ответ

1 голос
/ 05 сентября 2010

Ваш пример кода даже не скомпилируется ... сравните это:

Globals.pizzaCounter = searchService.GetCategoryCounter("pizza");

с этим:

public void GetCategoryCounter(string category)

Обратите внимание, что это пустой метод - так что вы не можетеприсвойте возвращаемое значение Globals.pizzaCounter.

. Следует иметь в виду, что это происходит асинхронно.Как вы сказали: «Если я добавлю несколько команд Debug.WriteLine, я увижу, что обратный вызов выполняется ПОСЛЕ возвращения ответа, то есть: возвращение не ожидает завершения асинхронной операции».В этом весь смысл того, что он асинхронный.Вы не хотите блокировать ваш поток пользовательского интерфейса, ожидающий возврата службы.

Вместо этого вы должны передать код извлечения службы для обратного вызова, который будет выполнен, когда ваша служба вернет некоторые данные.Затем необходимо выполнить маршалинг обратно в поток пользовательского интерфейса через Dispatcher, и , а затем может обновить текстовое поле.Ваш код уже выполняет некоторые из них, отправляя обратно в поток пользовательского интерфейса, а затем обновляя свойство, что вызовет событие PropertyChanged, позволяя пользовательскому интерфейсу знать, что нужно повторно получить данные из свойства.Тем не менее, похоже, что есть только один счетчик, а вы пытаетесь получить две разные категории.Вероятно, вам следует отделить саму службу от «счетчика категорий» (или чего-либо другого), который знает о службе поиска, но также относится к одной категории.Тогда у вас будет два экземпляра этого (но только один поисковый сервис);каждое текстовое поле будет привязано к соответствующему экземпляру счетчика категории.

...