'Why Do while in async method throughs error?

Im trying to implement a macro chained event on webbrowser control at winform.

Below is a button that opens webbrowser at https://example.com/login.

private void button1_Click(object sender, EventArgs e)
        {
            SuppressCookiePersistence();
            Form4 frm = new Form4(this);

            Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
AppDomain.CurrentDomain.FriendlyName, 11000);


                if (SetValueForUsername != "" && SetValueForPassword != "")
                {
                    frm.Show();
                    frm.webBrowser2.Navigate("https://example.com/login");
                }
                else
                {
                    MessageBox.Show("error: Credentials missing");
                }
        }

Below async void to invoke login

void dologin()
{
    webBrowser2.Document.GetElementById("username").SetAttribute("value", Form1.SetValueForUsername);
    webBrowser2.Document.GetElementById("password").SetAttribute("value", Form1.SetValueForPassword);
    HtmlElementCollection elc = this.webBrowser2.Document.GetElementsByTagName("button");
    foreach (HtmlElement el in elc)
    {
        if (el.GetAttribute("type").Equals("submit"))
        {
            el.InvokeMember("Click");
        }
    }
}

Below async void to click and load a page with indexes of 20 citizens per page

async Task CitizensPageLoadAsync()
{
    await PageLoad(1);
    HtmlElementCollection elc2 = this.webBrowser2.Document.GetElementsByTagName("input");
    foreach (HtmlElement el2 in elc2)
    {
        if (el2.GetAttribute("value").Equals("CitizensLoad"))
        {
            el2.InvokeMember("Click");
        }
    }

}

At this point i have a page with about 500 results indexed in pages of 20 results per page. So in order to find the page that contains the citizen im seeking im doing:

  async Task selectcitizen()
    {
        await PageLoad(2);
        bool Correct = false;
        int page = 1;
        do
        {
            page++;
            HtmlElementCollection elc2 = this.webBrowser2.Document.GetElementsByTagName("a");
            foreach (HtmlElement el2 in elc2)
            {
                if (el2.InnerText == citizenimlookingfor)
                {
                    Correct = true;
                    MessageBox.Show("Found");
                }
                else
                {
                    Correct = false;    webBrowser2.Navigate("https://example.com/displaycitizens.htm?d-16544-p=" + page + "");
                }
            }
        } while (Correct != true);
    }

all voids used here

public void webBrowser2_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
        dologin();
        CitizensPageLoadAsync();
        selectcitizen();
}

    

This is my wait method

private async Task PageLoad(int TimeOut)
        {
            TaskCompletionSource<bool> PageLoaded = null;
            PageLoaded = new TaskCompletionSource<bool>();
            int TimeElapsed = 0;
            webBrowser2.DocumentCompleted += (s, e) =>
            {
                if (webBrowser2.ReadyState != WebBrowserReadyState.Complete) return;
                if (PageLoaded.Task.IsCompleted) return; PageLoaded.SetResult(true);
            };
            //
            while (PageLoaded.Task.Status != TaskStatus.RanToCompletion)
            {
                await Task.Delay(10);
                TimeElapsed++;
                if (TimeElapsed >= TimeOut * 100) PageLoaded.TrySetResult(true);
            }
        }

Below is the error im getting while selectcitizen() excecutes and I cant figure out why:

Managed Debugging Assistant 'DisconnectedContext' 
  Message=Managed Debugging Assistant 'DisconnectedContext' : 'Transition into COM context 0xdea288 for this RuntimeCallableWrapper failed with the following error: System call failed. (Exception from HRESULT: 0x80010100 (RPC_E_SYS_CALL_FAILED)). This is typically because the COM context 0xdea288 where this RuntimeCallableWrapper was created has been disconnected or it is busy doing something else. Releasing the interfaces from the current COM context (COM context 0xdea340). This may cause corruption or data loss. To avoid this problem, please ensure that all COM contexts/apartments/threads stay alive and are available for context transition, until the application is completely done with the RuntimeCallableWrappers that represents COM components that live inside them.'


Solution 1:[1]

You can put your TaskCompletionSource at the scope of the class.

Start it on PageLoad(...) and complete it when webBrowser2.Completed is raised.

The while is not necessary with this approach. If you really need the timeout, you can use a Timer for that. At the scope of the class to.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Murilo Maciel Curti