我有这个代码,它应该从我构建的API返回一个身份验证令牌。我已经采用了异步方法,但现在我不知道在我的具体情况下要做什么来获取字符串标记,而不是任务,这是我的代码:
private async Task<string> AuthLogin(string user, string pass)
{
string username = user;
string password = pass;
string url = "http://localhost:8000/login";
try {
//retrieve auth token from /login
var client = new HttpClient ();
client.BaseAddress = new Uri(url);
string jsonData = "{\"username\":" + "\"" + username + "\",\"password\":" + "\"" + password + "\"}";
var content = new StringContent (jsonData, Encoding.UTF8, "application/type");
HttpResponseMessage resp = await client.PostAsync (new Uri (url), content);
string s = await resp.Content.ReadAsStringAsync ();
string result = Convert.ToString (s);
//some formatting to extract the actual token string
string[] tokenParts = result.Split (':');
string token = tokenParts[1].Replace ("\"", "");
return token;
}
catch (WebException) {
//error handling here
return null;
}
}
public string StoreTokenFromLogin(string user, string pass)
{
var token = AuthLogin (user, pass).Result;
System.Diagnostics.Debug.WriteLine(token);
System.Diagnostics.Debug.WriteLine(token.GetType ());
return token; //should be a string
}
然后,在我的页面视图中,我有一个执行此操作的事件处理程序:
loginButton.Clicked += (object sender, EventArgs e) => {
Authentication a = new Authentication();
string tok = a.StoreTokenFromLogin(usernameInput.Text, passwordInput.Text);
authLabel.Text = tok;
};
然而,当我点击按钮时,应用会冻结。 (我在Xamarin.Forms)。
答案 0 :(得分:4)
将您的事件处理程序更改为此
loginButton.Clicked += async(object sender, EventArgs e) =>
{
Authentication a = new Authentication();
string tok = await a.StoreTokenFromLogin(usernameInput.Text, passwordInput.Text);
authLabel.Text = tok;
};
等待调用获取令牌而不占用当前线程(可能是UI线程)。
你的StoreTokenFromLogin
到此。
public async Task<string> StoreTokenFromLogin(string user, string pass)
{
var token = await AuthLogin (user, pass);
System.Diagnostics.Debug.WriteLine(token);
System.Diagnostics.Debug.WriteLine(token.GetType ());
return token; //should be a string
}
基本上,我们的想法是,当您开始使用async
和await
时,它会通过您的方法调用冒泡,直到您遇到应该解决的问题并忘记({ {1}}),在本例中是您的事件处理程序。
如果您确实使用了async void
,那么您在等待并阻止使用Task.Result
- async
时阻止当前线程。