Example #1
0
        /// <summary>
        /// Occurs when a property on the monitored class changes
        /// </summary>
        /// <param name="sender">Object that fired the notification</param>
        /// <param name="propertyChangedEventArgs">Details about the event</param>
        private static void SelfOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            var self = (INotifyPropertyChanged)sender;

            TaskCompletionSource <bool> completionSource;

            if (!self.TaskCompleted(out completionSource))
            {
                return;
            }
            completionSource?.SetResult(true);
            CompletionSources.Remove(self);
            self.PropertyChanged -= SelfOnPropertyChanged;
        }
Example #2
0
        /// <summary>
        /// Check if the task has been completed
        /// </summary>
        /// <param name="self">Class instance that contains the properties</param>
        /// <param name="completionSource">Completion source that was used to create the monitored task</param>
        /// <returns>True - Task completed, otherwise false</returns>
        private static bool TaskCompleted(this INotifyPropertyChanged self,
                                          out TaskCompletionSource <bool> completionSource)
        {
            var taskCompleted = true;
            var properties    = self.GetBlockingProperties();

            completionSource = CompletionSources.ContainsKey(self) ? CompletionSources[self] : null;
            foreach (var property in properties)
            {
                var attribute = property.GetCustomAttribute <BlockingPropertyAttribute>();
                if (!property.GetValue(self).Equals(attribute.ExpectedValue))
                {
                    taskCompleted = false;
                }
            }
            return(taskCompleted);
        }
Example #3
0
        /// <summary>
        /// Returns a task that can be blocked against until a specific property changes.
        /// The property or properties should be marked with <see cref="BlockingPropertyAttribute"/> otherwise a completed task will be returned immediately.
        /// </summary>
        /// <param name="self">Class instance that contains the properties</param>
        /// <returns>Task that can be awaited until the decorated properties change</returns>
        public static Task <bool> BlockUntil(this INotifyPropertyChanged self)
        {
            TaskCompletionSource <bool> completionSource;

            if (self.TaskCompleted(out completionSource))
            {
                // The task is already finished
                return(Task.FromResult(true));
            }

            completionSource = new TaskCompletionSource <bool>();

            if (!CompletionSources.ContainsKey(self))
            {
                CompletionSources.Add(self, completionSource);
            }

            self.PropertyChanged += SelfOnPropertyChanged;
            return(completionSource.Task);
        }