UploadStringAsync在Windows Phone 8中不起作用
我是C#的新手,我想在Windows Phone应用程序中为我的RESTlike API创建库。UploadStringAsync在Windows Phone 8中不起作用
我的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);
VersionClass.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为基础
此:
VersionClass version = (VersionClass) apiTask.Result;
是死锁您的应用程序。
发生了什么是SynchronizationContext
正在尝试将管制员控制回之后的await
内部方法。
你应该始终await
上一个Task
:
VersionClass version = (VersionClass) await apiTask;
而且,要知道,你的UploadStringAsync
包装返回一个Task
已经取得了您通过WebClient.UploadStringTaskAsync
开箱即用的编辑
如果您选择继续您的Post
[R版本,你不应该await
对返回Task
,你应该让用户做到这一点,并注销从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;
}
Int以这种方式如何正确取消注册处理程序?我得到了“无法将匿名方法分配给隐式类型的局部变量”。错误,如果我尝试像在示例代码中那样做。 – 2014-09-03 17:28:01
@Mikhail我修复了我的代码。现在应该工作。 – 2014-09-03 18:08:53
您可以使用[UploadStringTaskAsync(HTTP:// MSDN .microsoft.com/en-us/library/hh193920(v = vs.110).aspx)而不是'UploadStringAsync'?我也猜你是死锁,因为你在你的任务上调用'.Result'而不是等待它。 – 2014-08-29 15:19:15