2010-03-28 25 views
9

hi cách dễ nhất để thực hiện các hoạt động asynch trên WPF và MVVM, cho phép người dùng nếu người dùng truy cập vào khi vào trường tôi muốn khởi chạy lệnh và sau đó quay trở lại trong khi một chuỗi sẽ thực hiện một số thao tác tìm kiếm quay lại và cập nhật các thuộc tính để thông báo có thể cập nhật các ràng buộc.làm thế nào để bạn triển khai các hoạt động không đồng bộ trong C# và MVVM?

cảm ơn!

Trả lời

3

Làm thế nào về một cá thể BackgroundWorker để gọi lệnh của bạn trên máy ảo?

Cập nhật: Làm xước đề xuất ở trên .. Có video trực tuyến về MVVM của Jason Dolinger .. Tôi khuyên bạn nên xem xét điều đó. Đó là một cách gọn gàng hơn khi chế độ xem mỏng/không chứa bất kỳ mã luồng nào.

Để tóm tắt:

  • VM ctor lưu trữ các đối tượng Dispatcher.CurrentDispatcher (chủ đề chính).
  • khi cập nhật cửa hàng sao lưu (kết quả), sử dụng _dispatcher.BeginInvoke(() => _results.AddRange(entries)) để giao diện người dùng được cập nhật chính xác.
+0

không ràng buộc sẽ phản ánh thay đổi với một cách giải quyết? bạn đã thử phương pháp này thành công chưa, cảm ơn Gishu –

+0

@Oscar: xem cập nhật ... hoặc tốt hơn nhưng hãy xem video đó. – Gishu

+3

Bạn có thể liên kết tới trang này bằng video: http://blog.lab49.com/archives/2650 – OwenP

8

Rob Eisenberg cho thấy triển khai thực sự sạch sẽ khi chạy các hoạt động không đồng bộ trong MVVM trong MIX10 talk. Anh ấy đã đăng mã nguồn lên blog của mình.

Ý tưởng cơ bản là bạn triển khai lệnh khi trả về một IEnumerable và sử dụng từ khóa lợi nhuận để trả về kết quả. Dưới đây là một đoạn mã từ cuộc trò chuyện của anh ấy, thực hiện tìm kiếm dưới dạng tác vụ nền:

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(); 
    } 

Hy vọng điều đó sẽ hữu ích.

+0

@Doug - Cảm ơn bạn đã liên kết. Đã cố gắng để quấn đầu của tôi xung quanh awesomeness trong một thời bây giờ .. :) – Gishu

0

Trong MSDN Điều Shawn Wildermuth của ông đã làm một cái gì đó như thế này: kiểm tra các bài viết ở đây: http://msdn.microsoft.com/en-us/magazine/dd458800.aspx

và bài viết trên blog gần đây của mình ở đây: 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; 
} 

với một thực hiện như thế này :

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; 
    } 
    } 
} 
Các vấn đề liên quan