异步方法调用两次

时间:2016-10-16 12:38:38

标签: c# .net asynchronous mvvm async-await

我从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(到它的结尾),现在它就完成了。

对不起名称约定。我会解决这个问题。

0 个答案:

没有答案