2015-10-07 7 views
0

Я пытаюсь получить данные с сервера, а потом мне нужно сделать несколько вещей с этими данными и другими функциями.Задача async и continuewith

Поскольку я получаю данные с сервера, я делал это с помощью async и continuewith functions.

Это мой код:

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

Как насчет включения разрыва при возникновении исключения при отладке. –

+2

Почему вы используете 'ContinueWith' вместо' await'? –

ответ

0

Проблема была совершенно иной.

Я выяснил, что я не могу преобразовать var, который был в динамическом объекте в int, и поэтому программа остановилась.

Я меняю эту строку: userID = dt ["ID"]; к этому: userID = Convert.ChangeType (dt ["ID"], typeof (int));

И теперь это работает.

Благодарим вас за все ваши предложения.

2

Когда он выпрыгивает, это означает, что задача прерывается (исключение), но не прерывает всю программу, поскольку это задача async.

Сделайте контрольную точку правой кнопкой мыши и проверьте, что находится внутри dt. Особенно у таких строк, как "ID", у вас часто бывают такие ошибки. Это может быть также "Id" или "id", который не равен нилю, но также не соответствует вашему "ID".

Удачи вам!

-2

Task.ContinueСначала начинается только после завершения первоначальной задачи. Я не уверен, если это поможет вам, но попробовать этот

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

И сделать ваш Логин нормальной функции аннулируется.

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(); 
    } 
} 
Смежные вопросы