WP8 HttpClient.PostAsync永远不会返回结果 [英] WP8 HttpClient.PostAsync never returns result
问题描述
我有一个Windows Phone 8应用,我在其中调用HttpClient.PostAsync,它从不返回结果。它只是坐在那里并挂起。如果我从控制台应用程序运行完全相同的代码,它将几乎立即返回结果。完成工作的所有代码都驻留在可移植的类库中。如果您能提供任何帮助,我将不胜感激。我在此状态下发现的所有其他问题都使用await client.PostAsync,我已经在做。
I have a Windows Phone 8 app where I am calling await HttpClient.PostAsync and it never returns a result. It just sits there and hangs. If I run the exact same code from a console app, it returns the result almost immediately. All of the code doing the work resides in a portable class library. I would appreciate any help you may be able to give. All of the other issues I have found on this state to use await client.PostAsync, which I am already doing.
我的类库中的代码如下:
The code in my class library is as such:
public class Authenticator
{
private const string ApiBaseUrl = "http://api.fitbit.com";
private const string Callback = "http://myCallbackUrlHere";
private const string SignatureMethod = "HMAC-SHA1";
private const string OauthVersion = "1.0";
private const string ConsumerKey = "myConsumerKey";
private const string ConsumerSecret = "myConsumerSecret";
private const string RequestTokenUrl = "http://api.fitbit.com/oauth/request_token";
private const string AccessTokenUrl = "http://api.fitbit.com/oauth/access_token";
private const string AuthorizeUrl = "http://www.fitbit.com/oauth/authorize";
private string requestToken;
private string requestTokenSecret;
public string GetAuthUrlToken()
{
return GenerateAuthUrlToken().Result;
}
private async Task<string> GenerateAuthUrlToken()
{
var httpClient = new HttpClient { BaseAddress = new Uri(ApiBaseUrl) };
var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0);
var oauthTimestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString(CultureInfo.InvariantCulture);
var oauthNonce = DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture);
var authHeaderValue = string.Format(
"oauth_callback=\"{0}\",oauth_consumer_key=\"{1}\",oauth_nonce=\"{2}\"," +
"oauth_signature=\"{3}\",oauth_signature_method=\"{4}\"," +
"oauth_timestamp=\"{5}\",oauth_version=\"{6}\"",
Uri.EscapeDataString(Callback),
Uri.EscapeDataString(ConsumerKey),
Uri.EscapeDataString(oauthNonce),
Uri.EscapeDataString(this.CreateSignature(RequestTokenUrl, oauthNonce, oauthTimestamp, Callback)),
Uri.EscapeDataString(SignatureMethod),
Uri.EscapeDataString(oauthTimestamp),
Uri.EscapeDataString(OauthVersion));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"OAuth",
authHeaderValue);
var content = new StringContent(string.Empty);
var response = await httpClient.PostAsync(RequestTokenUrl, content);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Request Token Step Failed");
}
var responseContent = await response.Content.ReadAsStringAsync();
var responseItems = responseContent.Split(new[] { '&' });
this.requestToken = responseItems[0];
this.requestTokenSecret = responseItems[1];
var url = string.Format("{0}?{1}&display=touch", AuthorizeUrl, this.requestToken);
return url;
}
public string CreateSignature(string url, string nonce, string timestamp, string callback)
{
// code removed
return signatureString;
}
private static byte[] StringToAscii(string s)
{
// code removed
return retval;
}
}
我有一个控制台应用程序,它会调用此库可以正常工作:
I have a console app that calls this library and it works with no problem:
public class Program
{
public static void Main(string[] args)
{
var o = new Program();
o.LinkToFitbit();
}
public void LinkToFitbit()
{
var authenticator = new Authenticator();
// this works and returns the url immediately
var url = authenticator.GetAuthUrlToken();
// code removed
}
}
当我从WP8应用程序运行时,到达库中的这一行时,它只是挂起:
When I run from my WP8 app, it just hangs when it gets to this line in the library:
var response = await httpClient.PostAsync(RequestTokenUrl, content);
这是我的WP8代码:
public partial class FitbitConnector : PhoneApplicationPage
{
public FitbitConnector()
{
InitializeComponent();
this.AuthenticateUser();
}
private void AuthenticateUser()
{
var authenticator = new Authenticator();
var url = authenticator.GetAuthUrlToken();
// code removed
}
}
推荐答案
此行阻止了UI线程:
public string GetAuthUrlToken()
{
return GenerateAuthUrlToken().Result;
}
之后的代码等待httpClient.PostAsync()
需要在UI线程中执行,但由于被阻止而无法执行。
The code after the await httpClient.PostAsync()
needs to be executed in the UI thread, but it can't be executed because is is blocked.
因此,替换为:
private void AuthenticateUser()
{
var authenticator = new Authenticator();
var url = authenticator.GetAuthUrlToken();
// code removed
}
使用以下命令:
private async void AuthenticateUser()
{
var authenticator = new Authenticator();
var url = await authenticator.GenerateAuthUrlToken();
// code removed
}
我正在使用异步
和等待
。您将需要公开 GenerateAuthUrlToken()
。您可以擦除 GetAuthUrlToken()
。
Notice I am using async
and await
. You will need to make GenerateAuthUrlToken()
public. You can erase GetAuthUrlToken()
.
简而言之,就是 Task< T>。结果
不是异步的。
In few words, Task<T>.Result
is not asynchronous.
这篇关于WP8 HttpClient.PostAsync永远不会返回结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!