我正在尝试从服务器获取数据,之后我需要对数据和其他功能做一些事情。
因为我从服务器获取数据,所以我使用async和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()
函数。
在进入下一个代码之前,我需要更改代码以使其运行整个函数?
提前谢谢!
答案 0 :(得分:4)
正如我在博客中所述,您绝不应该使用the Task
constructor或the Start
method。它们是在线程池线程上执行代码的极其过时的方法,由于LoginUser
是异步的,因此您的应用甚至不需要这样做。如果你 需要在线程池线程上执行代码,那么正确的API是Task.Run
,但在这种情况下你不需要它。
作为附注,在这种情况下你should not use ContinueWith
(也在我的博客上解释)。事实上,ContinueWith
is downright dangerous;你应该使用await
代替。
应用这些最佳做法后:
private async void login(object sender, EventArgs eventArgs)
{
SharedFunctions.showHide("Show", pBar, txt);
result = false;
if (validateScreen())
{
await LoginUser();
afterLogin();
}
}
答案 1 :(得分:2)
当它跳出时意味着任务中断(异常)但它不会破坏整个程序,因为这是一个异步任务。
正确设置断点并检查dt
内的内容。
特别是像"ID"
这样的字符串,你经常会遇到这样的错误。它可能也是"Id"
或"id"
,它不等于你的"ID"
。
答案 2 :(得分:0)
问题非常不同。
我发现我无法将动态对象中的var转换为int,这就是程序停止的原因。
我更改了这一行:userID = dt [“ID”];对此:userID = Convert.ChangeType(dt [“ID”],typeof(int));
现在它有效。
感谢大家的所有建议。
答案 3 :(得分:-2)
Task.ContinueWith仅在完成原始任务后启动。 我不确定这对你有帮助,但试试这个
private void login(object sender, EventArgs eventArgs)
{
SharedFunctions.showHide("Show", pBar, txt);
result = false;
if (validateScreen())
{
Task.Factory.StartNew(() => { LoginUser(); }).ContinueWith((t) => { afterLogin(); });
}
}
使您的登录成为正常的无效功能。