[英]Task async and continuewith
我正在嘗試從服務器獲取數據,之后我需要對該數據和其他功能做一些事情。
因為我從服務器獲取數據,所以我使用了異步和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"];
的行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"
,它不等於nill但也與您的"ID"
不匹配。
祝好運!
問題是非常不同的。
我發現無法將動態對象中的var轉換為int,這就是程序停止的原因。
我更改此行:userID = dt [“ ID”]; 為此:userID = Convert.ChangeType(dt [“ ID”],typeof(int));
現在就可以了。
謝謝大家的所有建議。
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(); });
}
}
並使您的登錄成為正常的void功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.