我从viewmodel做异步调用,所以我开始使用Nito.Mvvm.NotifyTask类。 它除了一个之外都很好用,我的异步方法调用了两次。我不是100%肯定是因为这个,但我没有任何其他的想法。
视图模型:
public class NewsPageViewModel : BindableBase
{
private INavigationService _navigationService;
private readonly Session _session;
public NotifyTask<ObservableCollection<PrivateNewsModel>> PrivateNews { get; }
private readonly PrivateNewsManager _privateNewsManager;
public NewsPageViewModel(INavigationService navigationService, ISecuredDataProvider securedDataProvider)
{
_navigationService = navigationService;
var store = securedDataProvider.Retreive(ConstantsService.ProviderName, UserManager.GetLastUser());
_session = new Session(UserManager.GetLastUser(), store.Properties.First().Value, store.Properties["PrivateFeedUrl"]);
var navigationParameters = new NavigationParameters { { "Session", _session } };
_privateNewsManager = new PrivateNewsManager(_session);
PrivateNews = NotifyTask.Create(GetPrivateNewsAsync());
}
private async Task<ObservableCollection<PrivateNewsModel>> GetPrivateNewsAsync()
{
return new ObservableCollection<PrivateNewsModel>
(await _privateNewsManager.GetPrivateNews());
}
}
异步方法:
public async Task<IEnumerable<PrivateNewsModel>> GetPrivateNews()
{
try
{
var gitHubPrivateFeedItems = await GetPrivateFeedItems();
var gitRemotePrivateFeedItems = new List<PrivateNewsModel>();
foreach ( var item in gitHubPrivateFeedItems )
{
var newsItem = new PrivateNewsModel
{
Title = item?.Element(XName.Get("title", ConstantsService.AtomNamespace))?.Value,
Published = TimeService.ConvertToFriendly(item?.Element(XName.Get("published", ConstantsService.AtomNamespace))?.Value),
ImageUrl = item?.Element(XName.Get("media", ConstantsService.AtomNamespace))?.Attribute(XName.Get("url", ConstantsService.AtomNamespace)).Value
};
var splitedTitle = newsItem.Title?.Split(' ');
if ( splitedTitle != null )
{
newsItem.Perfomer = splitedTitle[0];
newsItem.ActionType = splitedTitle[1];
newsItem.AdditionalTarget = newsItem.ActionType == "added"
? splitedTitle[2]
: string.Empty;
newsItem.Target = splitedTitle[splitedTitle.Length - 1];
}
gitRemotePrivateFeedItems.Add(newsItem);
}
return gitRemotePrivateFeedItems;
}
catch ( WebException ex )
{
throw new Exception("Something wrong with internet connection, try to On Internet " + ex.Message);
}
catch ( Exception ex )
{
throw new Exception("Getting repos from github failed! " + ex.Message);
}
}
private async Task<IEnumerable<XElement>> GetPrivateFeedItems()
{
var client = new HttpClient(new NativeMessageHandler());
var feed = await client.GetStringAsync(_session.GetPrivateFeedUrl());
if ( string.IsNullOrEmpty(feed) ) return new List<XElement>();
var parsedFeed = XElement.Parse(feed);
var entries = from entry in parsedFeed.Elements("{" + ConstantsService.AtomNamespace + "}entry") select entry;
return entries;
}
使用断点我看到它正在传递: ViewModel NotifyTask.Create - &gt; ViewModel GetPrivateNewsAsync - &gt; GetPrivateNews等待GetPrivateFeedItems - &gt; GetPrivateFeedItems等待GetStringAsync。 然后我认为它等待GetStringAsync完成,但因为它没有完成,它正在做我上面写的相同。当它完成上述工作时,GetStringAsync已经完成,它正在进行foreach循环和其他事情。 但是当循环结束并且我从GetPrivateNews返回时,它正在完成GetPrivateNewsAsync并转到GetPrivateFeedItems(但现在它在等待的行之后开始)并且在GetPrivateNews中进行foreach循环(在await之后相同)。然后用这个方法完成并转到viewmodel中的GetPrivateNewsAsync(到它的结尾),现在它就完成了。
对不起名称约定。我会解决这个问题。