2013-07-24 3 views
2

Я пытаюсь создать приложение, которое использует один знак с живым подключением и автоматически регистрирует пользователя на основе его информации о подключении.Как подождать, когда метод async вернется?

Право, когда мой запуск приложения я называю LiveConnectViewModel и называть эти две функций:

 public async void AuthInitialize() 
    { 
     string[] scopes = new[] { "wl.signin", "wl.basic", "wl.photos", "wl.emails", "wl.skydrive" }; 

     liveAuthClient = new LiveAuthClient(); 
     LiveLoginResult liveLoginResult = await liveAuthClient.InitializeAsync(scopes); 

     if (liveLoginResult.Status == LiveConnectSessionStatus.Connected) 
     { 
      App.Session = liveLoginResult.Session; 
     } 
     else 
     { 
      liveLoginResult = await liveAuthClient.LoginAsync(scopes); 
      App.Session = liveLoginResult.Session; 
     } 
     await LoadProfileAsync(); 
    } 

    public async Task LoadProfileAsync() 
    { 
     LiveConnectClient client = new LiveConnectClient(App.Session); 
     LiveOperationResult liveOperationResult = await client.GetAsync("me"); 
     LiveOperationResult liveOperationResultPicture = await client.GetAsync("me/picture"); 
     dynamic dynResult = liveOperationResult.Result; 
     dynResult.picture = liveOperationResultPicture.Result; 
     User currentUser = await UserViewModel.findOrCreateUserAsync(dynResult); 
     App.currentUser = currentUser; 
    } 

Сразу после того, что другой метод вызывается, когда заставка исчезла, и мой взгляд идет вверх.

Это выполнить этот код:

 public ProfilePageViewModel() 
    { 
     this.CurrentUser = App.currentUser; 
    } 

Теперь моя общая проблема заключается в сроках здесь. Когда я отлаживаю свое приложение, я вижу, что мой LiveConnectViewModel сначала вызывается и делает начальное соединение, затем LoadProfileAsync запускается до тех пор, пока моя программа не достигнет первого ожидания.

Сразу же при достижении этой точки мое приложение перестает работать над этим вызовом и продолжается. Теперь, когда дело доходит до моего ProfilePageViewModel, и он должен установить мое свойство «CurrentUser», ожидание по-прежнему не вернуло моего пользователя моему свойству App.CurrentUser, поэтому он говорит, что он равен нулю.

Обычно я просто подожду, пока свойство App.CurrentUser не будет установлено на что-то еще, кроме нуля, но я не могу избавиться от странного чувства, которое я либо пропустил, чтобы реализовать шаблон MVVM, либо что я сделал что-то чрезвычайно неправильно с ожиданием и асинхронным ...

Может ли кто-нибудь помочь мне прояснить это поведение?

+1

Удалите 'await' перед вызовом LoadProfileAsync(); «Ожидание» уже выполняется внутри LoadProfileAsync(). –

+0

Или наоборот, если это подходит вашему бизнесу, нужно более правильно. Нет необходимости ждать дважды, реклама делает это только смущает вопросы. –

ответ

4

Вы должны avoid async void, as I describe in a recent MSDN article.

После того, как вы сделаете AuthInitializeAsync возвращение Task вместо void, то вы можете await его перед созданием модели представления.

+0

Привет, Стивен, спасибо за ваш ответ. Я уже читал вашу статью MSDN в другом сообщении здесь, в stackoverflow. Моя проблема заключается в том, что если бы я изменил тип возвращаемого значения на «Задача», я не смог бы правильно вызвать эту функцию в моем конструкторе (это то, что я на самом деле делаю). Есть ли способ сделать это по-прежнему работать в моем конструкторе? – Evils

+1

У меня есть запись в блоге ['async' constructors] (http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html). В моих проектах MVVM я следую шаблону VM-first с использованием методов 'async' factory. Но если вы используете шаблон IoC или V-first, вам нужно использовать шаблон инициализации Async, как описано в моем блоге. –