首页 > 解决方案 > Task.Run 不在后台 c# 中运行任务

问题描述

我需要在不挂起 UI 的情况下在任务中调用一个函数,这就是我所做的,但面临挂起作为登录表单的主线程,那么缺少什么或者我以错误的方式实现?

private async void BtnLogin_Click(object sender, EventArgs e)
{
     await LoginAsync();
}

private async Task<bool> LoginAsync()
{
     LoginResponse loginResponse = await Task.Run(() =>
                    loginService.Login(new LoginModel { UserName = txtUN.Text, Password = txtPW.Text })
     );

     return loginResponse.Success;
}

后端代码:

public interface ILoginService
{
     Task<LoginResponse> Login(LoginModel model);
     Task<LogoutResponse> Logout();
}

public partial class LoginService : ILoginService
{
    public Task<LoginResponse> Login(LoginModel model)
    {
         return LoginAsync(model);
    }

    private async Task<LoginResponse> LoginAsync(LoginModel model)
    {
        for (int i = 0; i < 100000; i++)
        {
            Console.WriteLine(i);
        }

        string _Url = BaseUrl + "/login";
        try
        {
            model.CompanyName = System.Configuration.ConfigurationManager.AppSettings["Company_Name"];
            string Body = JsonConvert.SerializeObject(model);
            _logger.Info($"Login Request, Body: {Body}");
            HttpResponseMessage responseMessage = await client.PostAsync(new Uri(_Url), new 
            StringContent(Body, Encoding.UTF8, "application/json"));

            return JsonConvert.DeserializeObject<LoginResponse>(await 
            responseMessage.Content.ReadAsStringAsync());
         }
         catch (Exception e)
         {
            HandleException(e);
            return new LoginResponse
            {
               HttpStatus = HttpStatusCode.InternalServerError,
               Message = "Internal server error"
            };
         }
    }
}

所以任何人都可以指导我解决这个问题。

标签: c#.netmultithreadingasync-await

解决方案


Console.WriteLine(i);

是您的代码中唯一高度可疑的东西。这有点说明,但是当您使用时Task.Run,传入的操作将被调度到默认任务调度程序,ThreadPool如果您没有定义任何默认任务调度程序,那么线程池中的一个线程将接手工作而您的主 UI 线程正在自由等待另一个 UI 操作。因此,由于上述事实,您的 UI 应用程序不应该冻结

如果它看起来像冻结,您可能通过您Visual Studio的 F5 运行应用程序(如果 F5 表示在您的热键配置中开始调试)。因为Console.WriteLine将在 IDE 中某处的“输出”窗口中吐出所有索引值,并使对应用程序的操作无响应,即使应用程序中的 UI 实际上并未冻结。

CTRL + F5如果您仍想通过运行应用程序Visual Studio或直接执行,请尝试在 IDE 之外运行您的应用程序,只需(无需调试即可启动) .exe。然后我猜你可以看到你的 UI 工作正常。


推荐阅读