在异步调用WP7 [英] Async calls in WP7

查看:101
本文介绍了在异步调用WP7的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在WP7应用程序今天试验和已经打了一下墙壁。
我喜欢的UI和主要的应用程序code,但香港专业教育学院之间分离碰了壁。

I have been experimenting with WP7 apps today and have hit a bit of a wall. I like to have seperation between the UI and the main app code but Ive hit a wall.

我已成功实现了一个Web客户端请求,并得到一个结果,而是因为呼叫是异步我不知道如何将这种备份传递到用户界面级别。我似乎不能在等待破解的反应完成或任何东西。
我一定是做错了什么。

I have succesfully implemented a webclient request and gotten a result, but because the call is async I dont know how to pass this backup to the UI level. I cannot seem to hack in a wait for response to complete or anything. I must be doing something wrong.

(这是xbox360Voice库,我有下载在我的网站: http://www.jamesstuddart.co.uk/Projects/ASP.Net/Xbox_Feeds/ 这我移植到WP7作为测试)

(this is the xbox360Voice library that I have for download on my website: http://www.jamesstuddart.co.uk/Projects/ASP.Net/Xbox_Feeds/ which I am porting to WP7 as a test)

这里是后端code片断:

here is the backend code snippet:

    internal const string BaseUrlFormat = "http://www.360voice.com/api/gamertag-profile.asp?tag={0}";
    internal static string ResponseXml { get; set; }
    internal static WebClient Client = new WebClient();

    public static XboxGamer? GetGamer(string gamerTag)
    {
        var url = string.Format(BaseUrlFormat, gamerTag);

        var response = GetResponse(url, null, null);

        return SerializeResponse(response);
    }

    internal static XboxGamer? SerializeResponse(string response)
    {
        if (string.IsNullOrEmpty(response))
        {
            return null;
        }

        var tempGamer = new XboxGamer();
        var gamer = (XboxGamer)SerializationMethods.Deserialize(tempGamer, response);

        return gamer;
    }

    internal static string GetResponse(string url, string userName, string password)
    {


            if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
            {
                Client.Credentials = new NetworkCredential(userName, password);
            }

            try
            {
                Client.DownloadStringCompleted += ClientDownloadStringCompleted;
                Client.DownloadStringAsync(new Uri(url));

                return ResponseXml;
            }
            catch (Exception ex)
            {
                return null;
            }
        }



    internal static void ClientDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            ResponseXml = e.Result;
        }
    }

这是前端code:

and this is the front end code:

public void GetGamerDetails()
{
    var xboxManager = XboxFactory.GetXboxManager("DarkV1p3r");
    var xboxGamer = xboxManager.GetGamer();

    if (xboxGamer.HasValue)
    {
        var profile = xboxGamer.Value.Profile[0];
        imgAvatar.Source = new BitmapImage(new Uri(profile.ProfilePictureMiniUrl));
        txtUserName.Text = profile.GamerTag;
        txtGamerScore.Text = int.Parse(profile.GamerScore).ToString("G 0,000");
        txtZone.Text = profile.PlayerZone;
    }
    else
    {
        txtUserName.Text = "Failed to load data";
    }
}

现在我明白了,我需要放在 ClientDownloadStringCompleted 的东西,但我不确定是什么。

Now I understand I need to place something in ClientDownloadStringCompleted but I am unsure what.

推荐答案

您的问题是,一旦一个异步操作到code路径引入整个code路径需要成为异步

The problem you have is that as soon as an asynchronous operation is introduced in to the code path the entire code path needs to become asynchronous.


  • 因为的GetResponse 要求 DownloadStringAsync 它必须成为异步的,它不能返回一个字符串,它只能做上一个回调

  • 因为 GetGamer 要求的GetResponse 这是目前异步它不能返回一个 XboxGamer ,它只能做到这一点的回调

  • 因为 GetGamerDetails 要求 GetGamer 这是目前异步无法与以下的code中的继续打电话,只能这样做,它已收到后回电从 GetGamer

  • 因为 GetGamerDetails 现在是什么异步调用它也必须承认这一行为。

  • ....这样下去一路攀升到用户事件将发生有链条的顶端。

  • Because GetResponse calls DownloadStringAsync it must become asynchronous, it can't return a string, it can only do that on a callback
  • Because GetGamer calls GetResponse which is now asynchronous it can't return a XboxGamer, it can only do that on a callback
  • Because GetGamerDetails calls GetGamer which is now asynchronous it can't continue with its code following the call, it can only do that after it has received a call back from GetGamer.
  • Because GetGamerDetails is now asynchronous anything call it must also acknowledge this behaviour.
  • .... this continues all the way up to the top of the chain where a user event will have occured.

下面是一些空气code敲了一些不同步到code。

Here is some air code that knocks some asynchronicity in to the code.

public static void GetGamer(string gamerTag, Action<XboxGamer?> completed) 
{ 
    var url = string.Format(BaseUrlFormat, gamerTag); 

    var response = GetResponse(url, null, null, (response) =>
    {
        completed(SerializeResponse(response));
    }); 
} 


internal static string GetResponse(string url, string userName, string password, Action<string> completed)      
{      

   WebClient client = new WebClient();
   if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))      
   {      
       client.Credentials = new NetworkCredential(userName, password);      
   }      

   try      
   {      
        client.DownloadStringCompleted += (s, args) =>
        {
           // Messy error handling needed here, out of scope
           completed(args.Result);
        };
        client.DownloadStringAsync(new Uri(url));        
   }      
   catch     
   {      
      completed(null);      
   }      
}      


public void GetGamerDetails()              
{              
    var xboxManager = XboxFactory.GetXboxManager("DarkV1p3r");              
    xboxManager.GetGamer( (xboxGamer) =>              
    {
         // Need to move to the main UI thread.
         Dispatcher.BeginInvoke(new Action<XboxGamer?>(DisplayGamerDetails), xboxGamer);
    });

} 

void DisplayGamerDetails(XboxGamer? xboxGamer)
{
    if (xboxGamer.HasValue)              
    {              
        var profile = xboxGamer.Value.Profile[0];              
        imgAvatar.Source = new BitmapImage(new Uri(profile.ProfilePictureMiniUrl));              
        txtUserName.Text = profile.GamerTag;              
        txtGamerScore.Text = int.Parse(profile.GamerScore).ToString("G 0,000");              
        txtZone.Text = profile.PlayerZone;              
    }              
    else              
    {              
        txtUserName.Text = "Failed to load data";              
    }         
}

正如你所看到异步编程可以得到真的乱了。

As you can see async programming can get realy messy.

这篇关于在异步调用WP7的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆