嗨在WPF和MVVM上實現異步操作的最簡單方法是什麼?可以說用戶是否在用戶命中時輸入字段時我想啓動一個命令,然後返回而線程將執行一些搜索操作,然後返回返回並更新屬性,以便通知可以更新綁定。你如何在C#和MVVM中實現異步操作?
謝謝!
嗨在WPF和MVVM上實現異步操作的最簡單方法是什麼?可以說用戶是否在用戶命中時輸入字段時我想啓動一個命令,然後返回而線程將執行一些搜索操作,然後返回返回並更新屬性,以便通知可以更新綁定。你如何在C#和MVVM中實現異步操作?
謝謝!
BackgroundWorker如何在虛擬機上調用您的命令?
更新: 劃傷上述建議.. Jason Dolinger在MVVM上有一個在線視頻..我建議你看一看。這是一個更清晰的方式,視圖很薄/不包含任何線程代碼。
總結:
_dispatcher.BeginInvoke(() => _results.AddRange(entries))
以便正確更新用戶界面。羅布·艾森伯格表現出了非常乾淨的實現他的MIX10 talk期間運行在MVVM異步操作。他已經在他的博客上發佈了源代碼。
其基本思想是您將該命令實現爲返回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();
}
希望有所幫助。
@Doug - 感謝您的鏈接。一直試圖把我的頭圍繞在真棒一段時間.. :) – Gishu 2010-04-27 03:35:57
在肖恩Wildermuth的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;
}
}
}
該綁定是否會反映更改有一個解決方法?你有沒有試過這種方法成功,謝謝Gishu – 2010-03-28 03:57:41
@Oscar:看到更新...或更好的觀看那個視頻。 – Gishu 2010-03-28 15:59:40
本來很高興地鏈接到視頻頁面: http://blog.lab49.com/archives/2650 – OwenP 2010-04-26 20:53:28