异步 – WP7中的异步调用

我今天一直在尝试使用WP7应用程序并且已经打了一针墙.
我喜欢在用户界面和主应用程序代码之间进行分离,但我已经碰壁了.

我已经成功实现了webclient请求并获得了结果,但由于调用是异步的,我不知道如何将此备份传递到UI级别.我似乎无法等待对完成或任何事情的回应.
我一定做错了什么.

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

这是后端代码片段:

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

这是前端代码

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中放置一些内容,但我不确定是什么.

您遇到的问题是,只要在代码路径中引入异步操作,整个代码路径就需要变为异步.

>因为GetResponse调用DownloadStringAsync它必须变为异步,它不能返回一个字符串,它只能在回调时执行
>因为GetGamer调用现在异步的GetResponse,它不能返回XBoxGamer,它只能在回调时执行此操作
>因为GetGamerDetails调用现在异步的GetGamer,它不能在调用后继续使用它的代码,它只能在收到GetGamer的回调后才能继续执行.
>因为GetGamerDetails现在是异步的任何调用它也必须承认这种行为.
> ….这一直持续到用户事件发生的链顶部.

这里有一些空气代码可以解释代码中的某些异步性.

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

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


internal static string GetResponse(string url,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";              
    }         
}

正如您所看到的,异步编程可能会变得非常混乱.

相关文章

Windows2012R2备用域控搭建 前置操作 域控主域控的主dns:自...
主域控角色迁移和夺取(转载) 转载自:http://yupeizhi.blo...
Windows2012R2 NTP时间同步 Windows2012R2里没有了internet时...
Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...