UploadStringAsync赢得';无法在Windows Phone 8中工作

本文关键字:Phone Windows 工作 赢得 UploadStringAsync | 更新日期: 2023-09-27 18:20:09

我是C#的新手,我想在Windows Phone应用程序中为我的REST-like API装入库。

我的api结构有点像

http://mysiteurl/api/method_name.json

所以我想用(method_name,params)调用api并返回指定的类。

当我在我的Windows Phone 8.1程序上启动此代码时,冻结,什么也没发生。此外,我可以在服务器端看到任何东西(任何呼叫)

API.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using Newtonsoft.Json;
using SampleProg.Model;
namespace SampleProg.Lib
{
    public class Api
    {
        public async Task<VersionClass> versionInfo()
        {
            Debug.WriteLine("versionInfo()");
            var result = await this.Post<VersionClass>("version", "{}", null);
            Debug.WriteLine(result);
            return result;
        }
        public async Task<TReturnType> Post<TReturnType>(string methodName, string data, Dictionary<string, string> headers)
        {
            var webClient = new WebClient();
            webClient.Headers["Content-Type"] = "application/json";
            webClient.Encoding = Encoding.UTF8;
            var uri = new Uri(String.Format("http://mysiteurl/api/{0}.json", methodName));
            if (headers != null)
            {
                foreach (var key in headers.Keys)
                {
                    webClient.Headers[key] = headers[key];
                }
            }
            return await Post<TReturnType>(webClient, uri, data);
        }
        private async Task<TReturnType> Post<TReturnType>(WebClient webClient, Uri uri, string jsonData)
        {
            TReturnType returnObject = default(TReturnType);
            var taskCompletionSource = new TaskCompletionSource<TReturnType>();
            webClient.UploadStringCompleted += (s, e) =>
            {
                var result = e.Result;
                try
                {
                    Debug.WriteLine(result);
                    returnObject = JsonConvert.DeserializeObject<TReturnType>(result);
                    taskCompletionSource.SetResult(returnObject);
                }
                catch (Exception ex)
                {
                    var newEx = new Exception(
                      string.Format("Failed to deserialize server response: {0}", result), ex);
                    taskCompletionSource.SetException(newEx);
                }
            };
            webClient.UploadStringAsync(uri, "POST", jsonData);
            return await taskCompletionSource.Task;
        }
    }
}

App.xaml.cs(我从公共应用程序(){}调用它):

var api = new Api();
var apiTask = api.versionInfo();
VersionClass version = (VersionClass)apiTask.Result;
Debug.WriteLine(version.num);

版本Class.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace SampleProg.Model
{
    public class VersionClass
    {
        [JsonProperty("version")]
        public int num { get; set; }
    }
}

你能告诉我怎么了吗?我使用这个代码(在底部)http://sandor68.rssing.com/chan-11557297/all_p1.html作为基础

UploadStringAsync赢得';无法在Windows Phone 8中工作

这:

VersionClass version = (VersionClass) apiTask.Result;

正在使您的应用程序死锁。

发生的情况是,SynchronizationContext试图在内部方法中的await之后将控制封送回UI thread

您应该始终Task:上的await

VersionClass version = (VersionClass) await apiTask;

此外,请注意,返回TaskUploadStringAsync包装已经通过WebClient.UploadStringTaskAsync 为您制作了OOTB

编辑

如果您选择继续您的Post版本,您不应该在返回的Task上使用await,您应该让用户这样做,并从UploadStringCompleted:中注销处理程序

private async Task<TReturnType> Post<TReturnType>(WebClient webClient, Uri uri, string jsonData)
{
    TReturnType returnObject = default(TReturnType);
    var taskCompletionSource = new TaskCompletionSource<TReturnType>();
    UploadStringCompletedEventHandler handler = null;
    handler = (s, e) =>
    {
        webClient.UploadStringCompleted -= handler;
        var result = e.Result;
        try
        {
            Debug.WriteLine(result);
            returnObject = JsonConvert.DeserializeObject<TReturnType>(result);
            taskCompletionSource.SetResult(returnObject);
        }
        catch (Exception ex)
        {
            var newEx = new Exception(
              string.Format("Failed to deserialize server response: {0}", result), ex);
            taskCompletionSource.SetException(newEx);
        }
    };
    webClient.UploadStringCompleted += handler;
    webClient.UploadStringAsync(uri, "POST", jsonData);
    return taskCompletionSource.Task;
}