как Вы реализуете Асинхронные Операции в C# и MVVM?

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

спасибо!

9
задан Anthony Pegram 28 March 2010 в 03:59
поделиться

3 ответа

Как насчет экземпляра BackgroundWorker для вызова вашей команды на VM?

Обновление: Поскребите вышеупомянутое предложение... Есть онлайн-видео по MVVM от Джейсона Долингера... Я рекомендую вам взглянуть на него. Это более чистый способ, где представление является тонким/не содержит никакого потокового кода.

Подведем итоги:

  • VM ctor кэширует объект Dispatcher.CurrentDispatcher (основной поток).
  • при обновлении резервного хранилища (результатов), используйте _dispatcher.BeginInvoke( () => _results.AddRange( entries) ), чтобы пользовательский интерфейс обновлялся корректно.
3
ответ дан 4 December 2019 в 20:22
поделиться

Роб Эйзенберг продемонстрировал действительно чистую реализацию выполнения асинхронных операций в MVVM во время своего выступления MIX10 . Он разместил исходный код в своем блоге.

Основная идея состоит в том, что вы реализуете команду как возвращающую IEnumerable и используете ключевое слово yield для возврата результатов. Вот фрагмент кода из его выступления, который выполняет поиск в качестве фоновой задачи:

    public IEnumerable<IResult> ExecuteSearch()
    {
        var search = new SearchGames
        {
            SearchText = SearchText
        }.AsResult();

        yield return Show.Busy();
        yield return search;

        var resultCount = search.Response.Count();

        if (resultCount == 0)
            SearchResults = _noResults.WithTitle(SearchText);
        else if (resultCount == 1 && search.Response.First().Title == SearchText)
        {
            var getGame = new GetGame
            {
                Id = search.Response.First().Id
            }.AsResult();

            yield return getGame;
            yield return Show.Screen<ExploreGameViewModel>()
                .Configured(x => x.WithGame(getGame.Response));
        }
        else SearchResults = _results.With(search.Response);

        yield return Show.NotBusy();
    }

Надеюсь, что это поможет.

8
ответ дан 4 December 2019 в 20:22
поделиться

В статье MSDN Шона Вильдермута он сделал примерно следующее: посмотрите статью здесь: http://msdn.microsoft.com/en-us/magazine/dd458800.aspx

и его последняя запись в блоге здесь: http://wildermuth.com/2009 / 12/15 / Architecting_Silverlight_4_with_RIA_Services_MEF_and_MVVM _-_ Part_1

public interface IGameCatalog
{
  void GetGames();
  void GetGamesByGenre(string genre);
  void SaveChanges();

  event EventHandler<GameLoadingEventArgs> GameLoadingComplete;
  event EventHandler<GameCatalogErrorEventArgs> GameLoadingError;
  event EventHandler GameSavingComplete;
  event EventHandler<GameCatalogErrorEventArgs> GameSavingError;
}

с такой реализацией:

public class GameCatalog : IGameCatalog
{
  Uri theServiceRoot;
  GamesEntities theEntities;
  const int MAX_RESULTS = 50;

  public GameCatalog() : this(new Uri("/Games.svc", UriKind.Relative))
  {
  }

  public GameCatalog(Uri serviceRoot)
  {
    theServiceRoot = serviceRoot;
  }

  public event EventHandler<GameLoadingEventArgs> GameLoadingComplete;
  public event EventHandler<GameCatalogErrorEventArgs> GameLoadingError;
  public event EventHandler GameSavingComplete;
  public event EventHandler<GameCatalogErrorEventArgs> GameSavingError;

  public void GetGames()
  {
    // Get all the games ordered by release date
    var qry = (from g in Entities.Games
               orderby g.ReleaseDate descending
               select g).Take(MAX_RESULTS) as DataServiceQuery<Game>;

    ExecuteGameQuery(qry);
  }

  public void GetGamesByGenre(string genre)
  {
    // Get all the games ordered by release date
    var qry = (from g in Entities.Games
               where g.Genre.ToLower() == genre.ToLower()
               orderby g.ReleaseDate
               select g).Take(MAX_RESULTS) as DataServiceQuery<Game>;

    ExecuteGameQuery(qry);
  }

  public void SaveChanges()
  {
    // Save Not Yet Implemented
    throw new NotImplementedException();
  }

  // Call the query asynchronously and add the results to the collection
  void ExecuteGameQuery(DataServiceQuery<Game> qry)
  {
    // Execute the query
    qry.BeginExecute(new AsyncCallback(a =>
    {
      try
      {
        IEnumerable<Game> results = qry.EndExecute(a);

        if (GameLoadingComplete != null)
        {
          GameLoadingComplete(this, new GameLoadingEventArgs(results));
        }
      }
      catch (Exception ex)
      {
        if (GameLoadingError != null)
        {
          GameLoadingError(this, new GameCatalogErrorEventArgs(ex));
        }
      }

    }), null);
  }

  GamesEntities Entities
  {
    get
    {
      if (theEntities == null)
      {
        theEntities = new GamesEntities(theServiceRoot);
      }
      return theEntities;
    }
  }
}
0
ответ дан 4 December 2019 в 20:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: