Search code examples
c#visual-studiodispatchertimer

C# how to resume code when DispatcherTimer stops


So I have a class containing a function that can check whether an element in a website changes (In my example code this is class B). I also have multiple classes that need to use this function to see whether there is a change in a web element and then resume their function (In my example code this is class A). This is where I ran into a problem.

In my example code: The main function in class A wants to check if an element changes and calls a function in class B. Now, the main function in class A needs to wait for the method in class B to find a change in the specified web element. My question is: How can I make the main method in class A wait on the DispatcherTimer in class B?

static class A
{
    private static void main()
    {
        B.CheckWebElements("the element name");
        //NOW WE WANT TO WAIT UNTIL CLASS B IS DONE...
    }
}

Static class B
{
    private static DispatcherTimer dispatcherTimer;

    public static void CheckWebElements(string elementName)
    {
        //Get the last list
        var lastDoc = (HTMLDocument)Form.RosterBrowser.Document;
        List<string> lastDoc_list = ThisFuncReturnsList(lastDoc, elementName); //This function returns a list of all the child elements under the element with the name: elementName

        //Start the timer
        dispatcherTimer = new DispatcherTimer();
        dispatcherTimer.Tick += (sender, e) => Timer_Tick(sender, e, elementName, lastDoc_list);
        dispatcherTimer.Interval = new TimeSpan(0, 0, 2);
        dispatcherTimer.Start();
    }
    private static void Timer_Tick(object sender, EventArgs e, string elementName, List<string> lastDoc_list)
    {
        //Get the current list
        var thisDoc = (HTMLDocument)Form.RosterBrowser.Document;
        List<string> thisDoc_list = WebBrowserControl.GetWebData_RosterChoice(thisDoc, elementName);

        //Compare lists
        if (!thisDoc_list.SequenceEqual(lastDoc_list)) //With this function we compare the two lists
        {
            //HERE I WANT TO RESUME THE CODE IN CLASS A
            dispatcherTimer.Stop();
        }
        else
        {
            //HERE WE DO NOTHING FOR NOW
        }
    }
}

Solution

  • You should create a global variable:

    static class A
    {
        private static bool canContinue;
        public static void SetCanContinue() { canContinue = true; }
    }
    

    Then, in A.main() you spin and wait on this flag, await Dispatcher.Yield:

    private static async Task main()
    {
        B.CheckWebElements("the element name");
        //NOW WE WANT TO WAIT UNTIL CLASS B IS DONE...
        while (!canContinue) await Dispatcher.Yield();
    }
    

    Finally, in B, you need to call A.SetCanContinue() when ready.