C#如何在Web请求后从Task <string>获取字符串?

时间:2016-04-07 11:22:42

标签: c#

我有这个代码,它应该从我构建的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)。

1 个答案:

答案 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
}

基本上,我们的想法是,当您开始使用asyncawait时,它会通过您的方法调用冒泡,直到您遇到应该解决的问题并忘记({ {1}}),在本例中是您的事件处理程序。

如果您确实使用了async void,那么您在等待并阻止使用Task.Result - async时阻止当前线程。