2013-03-15 3 views
2

У меня возникла следующая проблема с моей реализацией RestSharp. Как я могу заставить приложение ждать ответа от ExecuteAsync(), прежде чем продолжить?Ожидание ExecuteAsync() result

Я пробовал различные решения:

Первый (метод не ждать ответа ExecuteAsync):

public Task<Connection> Connect(string userId, string password) 
    { 
     var client = new RestClient(_baseUrl) 
      { 
       Authenticator = new SimpleAuthenticator("user", userId, 
        "password", password) 
      }; 
     var tcs = new TaskCompletionSource<Connection>(); 
     var request = new RestRequest(AppResources.Authenticating); 
     client.ExecuteAsync<Connection>(request, response => 
      { 
       tcs.SetResult(new JsonDeserializer(). 
        Deserialize<Connection>(response)); 
      }); 
     return tcs.Task; 
    } 

Так что я попытался это, но приложение зависает:

public Task<Connection> Connect(string userId, string password) 
    { 
     EventWaitHandle executedCallBack = new AutoResetEvent(false); 
     var client = new RestClient(_baseUrl) 
      { 
       Authenticator = new SimpleAuthenticator("user", userId, 
        "password", password) 
      }; 
     var tcs = new TaskCompletionSource<Connection>(); 
     var request = new RestRequest(AppResources.Authenticating); 
     client.ExecuteAsync<Connection>(request, response => 
      { 
       tcs.SetResult(new JsonDeserializer(). 
          Deserialize<Connection>(response)); 
       executedCallBack.Set(); 
       }); 
     executedCallBack.WaitOne(); 
     return tcs.Task; 
    } 
+0

Что такое 'RestClient'? – Default

+1

Это происходит из библиотеки 'RestSharp', своего рода' WebClient' – user2169047

+0

, что такое Connection? Я не могу найти этот класс в RestSharp – adrian4aes

ответ

3

Я думаю, что вам не хватает точки Task и шаблона async/await.

Вы не ждите внутри этого метода, но поскольку вы возвращаете Task<>, он позволяет вызывающему абоненту ждать его асинхронно, если он выбирает.

Звонящий будет что-то вроде этого:

public async void ButtonClick(object sender, RoutedEventArgs args) 
{ 
    Connection result = await restClient.Connect(this.UserId.Text, this.Password.Text); 

     //... do something with result 
} 

компилятор знает, как сделать этот код, который очень похож на синхронном (блокирование) эквивалент, и превратить его в асинхронный код.

Обратите внимание на ключевые слова async и await, и обратите внимание, что Task<Connection> обернулся Connection.

Учитывая, что ваш первый фрагмент кода выглядит нормально.

Второй, вероятно, вызовет проблему, поскольку вы вводите другой механизм потоковой передачи (а именно семафор AutoResetEvent). Кроме того, @HaspEmulator прав - если это в потоке пользовательского интерфейса, это, как известно, затормозит WP приложение.

+0

Спасибо за ваше решение, но у меня все еще такая же проблема. Метод 'общественности Задача Connect (строка идентификатор пользователя, строка пароля) {...}' возвращение 'tcs.task'without ждет выполнение ' client.ExecuteAsync (.. .) ' , поэтому результат всегда равен нулю – user2169047

+1

Да, это именно то, что он должен делать. Вы получите результат только в том случае, если вы «ждете» его. –

0

Это выглядит ужасно похоже на проблемы, с которыми сталкиваются многие люди: вы не должны блокировать пока выполняете WebRequest (прямо или косвенно через некоторые другие библиотеки). Кажется, он зашел в тупик. Избегайте этого.