Как получить значение из асинхронного метода, расположенного в отдельном классе? - PullRequest
1 голос
/ 13 октября 2011

Я работал над приложением, которое делает довольно много запросов, используя класс HttpWebRequest для получения данных из Интернета.Теперь мое приложение выполняет почти идентичные вызовы в нескольких частях моего приложения.Это превращается в проблему, потому что я дублирую много кода.

Идеальным решением было бы заключить в себе логику, которая делает вызовы в Интернете, в своем собственном классе, чтобы обновление было простым и его можно было повторно использовать в моем приложении.Я просто не уверен, как сделать асинхронный вызов в отдельном классе и вернуть значение моему основному коду, чтобы я мог обновить пользовательский интерфейс данными.

Может кто-нибудь дать мне несколько советов о том, какчтобы это произошло?Я знаю, что это должно быть возможно, потому что разработчики делают это все время, следуя шаблону MVVM.

Я использую Silverlight / C #.

Ответы [ 2 ]

1 голос
/ 13 октября 2011

У нас есть такой код в нашем приложении Silverlight для использования со службами данных WCF.Возможно, вы могли бы сделать что-то похожее для ваших веб-запросов:

Вот пример кода (не проверен) (обратите внимание, что на самом деле я никогда не писал ни одного кода, выполняющего веб-запросы, но, возможно, шаблон асинхронности похож на другиематериал, который я сделал в Silverlight):

public class WebRequesterHelper
{
  Action _callback;

  public void MakeWebRequest(object whateverYouNeedForTheWebRequest, Action callback)
  {
    _callback = callback;

    //Make your async web request here, passing the helper object's callback.

    IAsyncResult result = yourWebRequestObject.BeginGetResponse(new AsyncResultCallback(WebRequestCallback), yourRequestState);
  }

  public void WebRequestCallback(IAsyncResult result)
  {
    //Do whatever you need to do as a result of the web request, then call the callback.
    if (_callback != null) callback();
  }
}

В вашем коде, который хочет сделать веб-запрос:

var helper = new WebRequestHelper();
//Setup the web request

object request = SetUpYourWebRequest();

helper.MakeWebRequest(request, OnWebRequestCompleted);

Ваш обратный вызов помощника:

public void OnWebRequestCompleted()
{
  //Web request is finished, what do I want to do?
}

Обратите внимание, что вы можете захотеть, чтобы ваш обратный вызов (который вы передаете объекту WebRequestHelper) принял параметр, и вы могли бы передать информацию обратно из функции обратного вызова веб-запроса (в объекте WebRequestHelper).

1 голос
/ 13 октября 2011

Поскольку ваш код для загрузки в Интернете - это, по сути, ваша бизнес-логика, я бы определенно инкапсулировал его в своем собственном классе, как вы и планировали.Затем вы должны использовать события для уведомления вашего пользовательского интерфейса об изменениях состояния.

Например, ваш экземпляр "WebRequestManager" может инкапсулировать всю обработку потока и будет вызывать события, чтобы пользовательский интерфейс мог соответствующим образом реагировать.Вы бы инициировали событие на TaskCompleted и, возможно, также через определенные промежутки времени, чтобы обеспечить интересную обратную связь, такую ​​как AsyncProgressChanged.

ПРИМЕЧАНИЕ. В порядке соглашения я бы предпочел префикс любых событий, которые, вероятно, будутвызывается из потока, отличного от исходного, вызывающего поток с именем «Async», так что обработчик пользовательского интерфейса может присоединиться к потоку пользовательского интерфейса.

...