我尝试使用Microsoft.Http的API.我按照这里提供的样本http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client,但我的任务没有完成,保持状态WaitingForActivation
private void btnLogin_Click(object sender, EventArgs e) { try { var t = Api.LoginAsync( tbUsername.Text, tbPassword.Text); t.Wait(); _Token = t.Result; } catch (Exception ex) { ShowError(ex.Message); } }
static class Api { private const string URLBase = "http://localhost:28929/"; public static async TaskLoginAsync(string Username, string Password ) { using (var client = new HttpClient()) { client.BaseAddress = new Uri(URLBase); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // HTTP POST var VM = new Usuario() { Username = Username, Password = Password}; HttpResponseMessage response = await client.PostAsJsonAsync("api/login", VM); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsAsync (); } else { throw new ApplicationException("No se pudo ingresar. Error: " + response.StatusCode.ToString()); } } } }
您还需要创建事件处理程序async
:
private async void btnLogin_Click(object sender, EventArgs e) { try { _Token = await Api.LoginAsync( tbUsername.Text, tbPassword.Text); } catch (Exception ex) { ShowError(ex.Message); } }
那里有僵局.
该LoginAsync
方法将同步运行,直到第一个await
(await client.PostAsJsonAsync("api/login", VM);
).然后它将返回到事件处理程序,并且UI线程将被阻止t.Wait()
.当await client.PostAsJsonAsync("api/login", VM);
完成时,方法的其余部分可以运行.问题是它必须在UI线程上运行(在同一个同步上下文中),该线程被阻塞,等待任务完成.僵局.
您还必须await
在事件处理程序中使用
private async void btnLogin_Click(object sender, EventArgs e) { try { _Token = await Api.LoginAsync( tbUsername.Text, tbPassword.Text); } catch (Exception ex) { ShowError(ex.Message); } }
您可以在Stephen Cleary的博客上找到详细的解释.