Skip to content

Automation.AddAutomationPropertyChangedEventHandler calls freezes app #6

Open

Description

@vforvoid

It seems like calling this method makes my application freeze.
It is happening on Factory.AddPropertyChangedEventHandler call
https://github.com/JakeGinnivan/UIAComWrapper/blob/master/UIAComWrapper/Automation.cs#L127

Any ideas why is it happening and how I can fix it?
Thanks in advance.

Activity

  1. Tankatronic commented on Sep 16, 2015

    @Tankatronic

    Hey vforvoid, I tried to replicate the issue in a small console application and I am able to call the method without the freezing you describe. Are you trying to subscribe to a specific AutomationElement? What TreeScope are you providing?

    This is the code I compiled to test that method. If you are subscribing to a specific element that is giving you problems, try using this test app to subscribe to the element in question in place of the RootElement I was using. This application was run on a Windows 7 OS.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Automation;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                SubscribeToPropertyChanged();
            }
    
            public static void SubscribeToPropertyChanged()
            {
                try
                {
                    // Subscribe to Property Changed
                    Automation.AddAutomationPropertyChangedEventHandler(
                        AutomationElement.RootElement,
                        TreeScope.Children,
                        new AutomationPropertyChangedEventHandler(OnPropertyChanged),
                        AutomationElement.AutomationIdProperty);
    
                    while (true)
                    {
                        System.Threading.Thread.Yield();
                    }
    
                }
                catch (ElementNotAvailableException) { }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
    
            private static void OnPropertyChanged(object sender, AutomationPropertyChangedEventArgs e)
            {
                return;
            }
        }
    }
    
  2. vforvoid commented on Sep 17, 2015

    @vforvoid
    Author

    Hey Tankatronic. Many thanks for taking a look at it!

    Seems like your code example works just fine. I've tried it on a couple of different applications elements without any problems. I made a project last week using outdated .NET wrapper for UIA, going to try to replace it with your wrapper in a day or two to see what happens and update you with results.

  3. vforvoid commented on Sep 22, 2015

    @vforvoid
    Author

    Ok, sorry for making you wait. I think it is some threading probmels. Check out this modified snippet:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Automation;
    using System.Windows;
    
    namespace UIAComWrapperTest
    {
        class Program
        {
            static AutomationElement element;
            static AutomationPropertyChangedEventHandler handler;
            static AutomationFocusChangedEventHandler focusHandler;
    
            static void Main(string[] args)
            {
                SubscribeToFocusChange();
            }
    
            public static void SubscribeToFocusChange()
            {
                focusHandler = new AutomationFocusChangedEventHandler(OnFocusChange);
                Automation.AddAutomationFocusChangedEventHandler(focusHandler);
    
                while (true)
                {
                    System.Threading.Thread.Yield();
                }
            }
    
            private static void OnFocusChange(object src, AutomationFocusChangedEventArgs e)
            {
                try
                {
                    System.Diagnostics.Debug.WriteLine("Focus changed");
                    var newElement = src as AutomationElement;
                    if (element != null && element == newElement)
                        return;
                    element = newElement;
                    InitializePropertyChanged();
                }
                catch (ElementNotAvailableException ex) 
                {
                    Console.WriteLine(ex);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
    
            public static void InitializePropertyChanged()
            {
                try
                {
                    //element = AutomationElement.FromPoint(new Point(1400, 800));
                    //element = AutomationElement.FromPoint(new Point(1200, 681));
                    System.Diagnostics.Debug.WriteLine("Class: " + element.Current.LocalizedControlType);
                    var patterns = element.GetSupportedPatterns();
                    if (!patterns.Contains(ValuePattern.Pattern))
                        return;
                    var valuePattern = (ValuePattern)element.GetCurrentPattern(ValuePattern.Pattern);
                    var value = valuePattern.Current.Value;
                    handler = new AutomationPropertyChangedEventHandler(OnPropertyChanged);
                    // Uncomment task starting code to bypass freezes (maybe i should use task queue on the main thread instead?). It will lead to a bug when we're able to subscribe to the same element's event multiple times
                    // So we should keep track of elements and properties subscriptions if we don't want to run into it. 
                    // I think .NET vanilla wrapper had no such issue, but it's manageable.
                    //Task.Factory.StartNew(() =>
                    //{
                        // This will freeze unless called from separate thread. This wouldn't freeze in vanilla wrapper.
                        Automation.AddAutomationPropertyChangedEventHandler(
                            element,
                            TreeScope.Subtree,
                            handler,
                            ValuePattern.ValueProperty);
                        System.Diagnostics.Debug.WriteLine("Subscribed to cahnges");
                    //}
                    //);
                }
                catch (ElementNotAvailableException) { }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
    
            public static void OnPropertyChanged(object sender, AutomationPropertyChangedEventArgs e)
            {
                var valuePattern = (ValuePattern)(sender as AutomationElement).GetCurrentPattern(ValuePattern.Pattern);
                var value = valuePattern.Current.Value;
                System.Diagnostics.Debug.WriteLine("New value: " + value);
            }
        }
    
    }
    
  4. Tankatronic commented on Sep 25, 2015

    @Tankatronic

    Hey vforvoid,

    I will run your test to see if I experience the same issue the first monday of October. I am currently out of the country right now visiting one of our offices and won't have time until I return. Just wanted to let you know I won't leave you hanging.

  5. vforvoid commented on Oct 27, 2015

    @vforvoid
    Author

    Good day. I wonder if you have any time now to take a look at this?

  6. JakeGinnivan commented on Oct 28, 2015

    @JakeGinnivan
    Member

    Did one of you want contributor rights to this project, I don't have time to maintain at the moment and more than happy to add others

  7. vforvoid commented on Oct 28, 2015

    @vforvoid
    Author

    Thanks, I'm quite busy with my current project atm, but if I will end up changing UIAComWrapper's code, I will create pull request for sure.

  8. Tankatronic commented on Oct 28, 2015

    @Tankatronic

    I am currently on vacation but will get back to you in a couple weeks when
    I return.

    On Wed, Oct 28, 2015, 3:25 AM vforvoid notifications@github.com wrote:

    Thanks, I'm quite busy with my current project atm, but if I will end up
    changing UIAComWrapper's code, I will create pull request for sure.

    —
    Reply to this email directly or view it on GitHub
    #6 (comment)
    .

  9. ivan-danilov commented on Dec 29, 2015

    @ivan-danilov
    Contributor

    @vforvoid I've tried your code and it does not freeze for me. At least I see a lot of "Subscribed to cahnges" messages in the output...
    You could also try to update package to the last version (just published) and see exactly where the freeze happened (VS should silently download library sources from github and allow to debug in the new version, as new package includes pdb).

  10. vforvoid commented on Dec 29, 2015

    @vforvoid
    Author

    Hey, thanks, I'm out due to new year, will try to check it as soon as I get
    to my pc
    On Dec 29, 2015 07:45, "ivan-danilov" notifications@github.com wrote:

    @vforvoid https://github.com/vforvoid I've tried your code and it does
    not freeze for me. At least I see a lot of "Subscribed to cahnges" messages
    in the output...
    You could also try to update package to the last version (just published)
    and see exactly where the freeze happened (VS should silently download
    library sources from github and allow to debug in the new version, as new
    package includes pdb).

    —
    Reply to this email directly or view it on GitHub
    #6 (comment)
    .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions