异步执行任务并继续执行

本文关键字:执行 继续 执行任务 异步 | 更新日期: 2023-09-27 18:16:40

我试图从服务器获取数据,之后我需要做一些事情与数据和其他功能。

因为我从服务器获取数据,所以我使用异步和continuewith函数。

这是我的代码:

private void login(object sender, EventArgs eventArgs)
{
    SharedFunctions.showHide("Show", pBar, txt);
    result = false;
    if (validateScreen())
    {
        Task task = new Task(() => LoginUser().ContinueWith((t) =>
        {
            afterLogin();
        }));
        task.Start();
    }
}
private void afterLogin()
{
    if (result)
    {
        SharedFunctions.saveDataOnDevice(userID, storeID, permission);
        StartActivity(typeof(SplashScreen));
        Finish();
    }
    else
    {
        SharedFunctions.showHide("Hide", pBar, txt);
        SharedFunctions.showPopUp(this, GetString(Resource.String.error_login), GetString(Resource.String.wrong_name_and_password));
    }
}
private async Task LoginUser()
{
    string userName = uName.Text;
    string password = pass.Text;
    password = SharedFunctions.encrypt(password);
    var client = new RestClient("........");
    string resourceStr = @"api/base/....";
    var request = new RestRequest(Method.POST)
    {
        Resource = resourceStr,
        RequestFormat = DataFormat.Json
    };
    request.AddBody(new { UserName = userName, Password = password });
    var response = await client.ExecuteTaskAsync<dynamic>(request);
    var dt = response.Data;
    if (dt != null)
    {
        userID = dt["ID"];
        storeID = dt["StoreID"];
        permission = dt["Permission"];
        result = true;
    }
    else
        result = false;
}

我的主要问题是,在我得到数据之后,就在这个代码之后:if (dt != null) .

当我尝试调试代码时,它到达userID = dt["ID"];行,甚至在执行之前,它跳转到afterLogin()函数。

我需要改变我的代码,使其运行整个函数之前去下一个?

提前感谢!

异步执行任务并继续执行

正如我在博客中所描述的那样,您永远不应该使用Task构造函数或Start方法。它们是在线程池线程上执行代码的非常过时的方法,因为LoginUser是异步的,所以你的应用程序甚至不需要这样做。如果确实需要在线程池线程上执行代码,那么正确的API是Task.Run,但在这种情况下,您不需要它。

作为旁注,在这种情况下也不应该使用ContinueWith(在我的博客上也有解释)。事实上,ContinueWith是彻头彻尾的危险;你应该用await代替。

应用这些最佳实践后:

private async void login(object sender, EventArgs eventArgs)
{
  SharedFunctions.showHide("Show", pBar, txt);
  result = false;
  if (validateScreen())
  {
    await LoginUser();
    afterLogin();
  }
}

当它跳出时,意味着任务中断(异常),但它不会中断整个程序,因为这是一个异步任务。

在这里设置一个断点并检查dt内部的内容。特别是像"ID"这样的字符串,你经常会有这样的错误。也可以是"Id""id",它们不等于nil,但也不匹配您的"ID"

祝你好运!

问题完全不同。

我发现我不能将动态对象中的var转换为int,这就是程序停止的原因。

我修改这一行:userID = dt["ID"];userID =转换。ChangeType (dt (" ID "), typeof (int));

现在它工作了。

谢谢大家的建议。

任务。ContinueWith仅在原始任务完成后启动。我不确定这是否对你有帮助,但试试这个

private void login(object sender, EventArgs eventArgs)
{
    SharedFunctions.showHide("Show", pBar, txt);
    result = false;
    if (validateScreen())
    {
        Task.Factory.StartNew(() => { LoginUser(); }).ContinueWith((t) => { afterLogin(); });
    }
}

并使您的登录成为一个正常的void函数