簡體   English   中英

任務異步並繼續

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM