当前位置:  开发笔记 > 编程语言 > 正文

任务一直在等待激活

如何解决《任务一直在等待激活》经验,为你挑选了2个好方法。

我尝试使用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);
        }
    }

Api课

static class Api {
    private const string URLBase = "http://localhost:28929/";

    public static async Task LoginAsync(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());
            }
        }
    }
}

在此输入图像描述



1> Daniel Mann..:

您还需要创建事件处理程序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);
    }
}


调用`Wait`或检查任务上的`Result`属性可以(并且会)导致死锁.

2> Jakub Lortz..:

那里有僵局.

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的博客上找到详细的解释.

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有