Хорошо, я понял это, я думаю ..
Это было все время, я просто пропустил это.
1) вы асинхронно получаете данные."Request.BeginGetResponse (result => ....);"произойдет когда-нибудь в будущем, но вы вернете свой результат до того, как это произойдет .. код продолжает двигаться, он не ждет вашего результата.Вот что вы хотите сделать:
public class SiteStats
{
public string seller_name { get; set;}
public static void GetSiteStatistics(string subdomain, string apiKey, Action<SiteStats> callback)
{
SiteStats retVal = null;
HttpWebRequest request = WebRequest.Create(string.Format("https://{0}.chargify.com/stats.json", subdomain)) as HttpWebRequest;
NetworkCredential credentials = new NetworkCredential(apiKey, "X");
request.Credentials = credentials;
request.Method = "GET";
request.Accept = "application/json";
request.BeginGetResponse(result =>
{
using (var response = request.EndGetResponse(result))
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string stats = reader.ReadToEnd();
retVal = Json.Deserialize<SiteStats>(stats);
callback(retVal);
}
}
}, request);
//return retVal; // you can't return here
}
}
Соответствующий код ViewModel будет выглядеть примерно так:
public SiteDetailViewModel(string subdomain) : this()
{
SiteStats.GetSiteStatistics(subdomain, "apiKeyHere", (result)=> {
// Note you may need to wrap this in a Dispatcher call
// as you may be on the wrong thread to update the UI
// if that happens you'll get a cross thread access
// you will have to expose the dispatcher through some
// other mechanism. One way to do that would be a static
// on your application class which we'll emulate and
// I'll give you the code in a sec
myRootNamespace.App.Dispatcher.BeginInvoke(()=>this._siteStats = results);
});
}
Вот изменения, которые необходимо внести в класс Application (I 'Я не уверен, насколько это безопасно для потоков, и я действительно рекомендую вам использовать что-то вроде DispatcherHelper MVVMLight.
public partial class App : Application
{
public static Dispatcher Dispatcher { get; private set; } // Add this line!!
// More code follows we're skipping it
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new MainPage();
Dispatcher = this.RootVisual.Dispatcher; // only add this line!!
}
private void Application_Exit(object sender, EventArgs e)
{
// Do this to clean up
Dispatcher = null;
}
}