Доступ и изменение веб-браузера winform из потока - PullRequest
1 голос
/ 09 января 2012

Я работаю над приложением Windows, в котором у меня есть tabControl, в котором пользователь может открыть несколько вкладок, как в IE. Теперь мне нужно получить доступ к выбранной вкладке, а затем выполнить некоторую операцию с открытым документом.

Я могу получить к нему доступ, но после доступа к выбранной вкладке и выполнения операции

приложение зависает, пока я использую другой поток для выполнения этой задачи.

Подскажите, пожалуйста, как мне это сделать.

Я использую .net 4.0. C #

См. Ниже код, этот код при нажатии кнопки

   TextToSpeechThread = new Thread(new ThreadStart(ReadWebDocument));
        TextToSpeechThread.Name = ApplicationManager.GlobalThreadNaming.TextToSpeech.ToString();
        TextToSpeechThread.SetApartmentState(ApartmentState.STA);
        TextToSpeechThread.Start();

И это метод Thread для вызова операции

 browserTabControl.Invoke(new MethodInvoker(delegate
        {

            browserTabControl.SelectedTab.Controls[0].Invoke(new MethodInvoker(delegate
            {
                WebBrowser _browser = (WebBrowser)(browserTabControl.SelectedTab.Controls[0]);

                my_Voice.Speak(_browser.DocumentTitle.ToString(), my_Spflag);

                foreach (var link in _browser.Document.All)
                {
                    HtmlElement elem = (HtmlElement)(link);
                    Thread tempThread = new Thread(new ParameterizedThreadStart(HighlightingWebDocument));
                    tempThread.Start(elem);

                    if (elem.TagName == "A")
                    {
                        if (elem.InnerText != null)
                        {
                            if (elem.InnerText.ToString() != "")
                            {
                                my_Voice.Speak(elem.InnerText.ToString(), my_Spflag);
                            }
                        }
                    }
                    if (elem.TagName == "DIV")
                    {
                        if (elem.InnerText != null)
                        {
                            if (elem.InnerText.ToString() != "")
                            {
                                my_Voice.Speak(elem.InnerText.ToString(), my_Spflag);
                            }
                        }
                        //my_Voice.Speak(elem.TagName.ToString(), my_Spflag);
                    }
                    if (elem.TagName == "IFRAME")
                    {
                        if (elem.InnerText != null)
                        {
                            if (elem.InnerText.ToString() != "")
                            {
                                my_Voice.Speak(elem.InnerText.ToString(), my_Spflag);
                            }
                        }
                    }
                    if (elem.TagName == "SPAN")
                    {
                        if (elem.InnerText != null)
                        {
                            if (elem.InnerText.ToString() != "")
                            {
                                my_Voice.Speak(elem.InnerText.ToString(), my_Spflag);
                            }
                        }
                    }
                    if (elem.TagName == "LINK")
                    {
                        if (elem.InnerText != null)
                        {
                            if (elem.InnerText.ToString() != "")
                            {
                                my_Voice.Speak(elem.InnerText.ToString(), my_Spflag);
                            }
                        }
                    }
                    if (elem.TagName == "INPUT")
                    {
                        if (elem.InnerText != null)
                        {
                            if (elem.InnerText.ToString() != "")
                            {
                                my_Voice.Speak(elem.InnerText.ToString(), my_Spflag);
                            }
                        }

                    }
                    Thread.Sleep(150);
                }
            }));


        }));

Теперь предоставьте полезную ссылку ...

Это еще один подход, предложенный вами, ребята ..

Объявление делегата

delegate void HighlightBrowsercontent(HtmlElement elem);
    HighlightBrowsercontent highLightBrowsercontent = null;

при загрузке формы

  public Form1()
    {
        InitializeComponent();

        // initialise the delegate to point to an implemntation

        highLightBrowsercontent = new HighlightBrowsercontent(OnHighLightContent);

    }

При нажатии на кнопку я хочу прочитать содержимое, а также выделить ссылки.

  private void button1_Click(object sender, EventArgs e)
    {
        HtmlElementCollection links = webBrowser1.Document.Links;

        this.backgroundWorker2.RunWorkerAsync(links);
    }

И, наконец, этот процесс, который я хочу выполнить.

 private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
    {
        IAsyncResult res = BeginInvoke(myEnableCancel, new object[] { true });
        ReadDocumetnAsync((HtmlElementCollection)(e.Argument));
        BeginInvoke(myEnableCancel, new object[] { false });
    }

    void ReadDocumetnAsync(HtmlElementCollection elemCollection)
    {
        foreach (var elem in elemCollection)
        {
            HtmlElement elem1 = (HtmlElement)(elem);

            SpeechLib.SpVoice myVoice = new SpeechLib.SpVoice(); ;
            if (elem1.InnerText != null)
            {
                BeginInvoke(highLightBrowsercontent, elem);
                myVoice.Speak(elem1.InnerText);
                System.Threading.Thread.Sleep(450);

                IAsyncResult ar = BeginInvoke(highLightBrowsercontent, elem);// Update the screen
                // Wait until the folder has been created before proceeding with the content of the folde
                while (!ar.IsCompleted)
                {
                    Application.DoEvents();
                    ar.AsyncWaitHandle.WaitOne(-1, false);
                }


            }

        }

    }
 public void OnHighLightContent(HtmlElement element)
    {
        HtmlDocument doc2 = webBrowser1.Document as HtmlDocument;
        toolStripStatusLabel2.Text = element.OuterHtml;
        element.Focus();
        element.ScrollIntoView(false);
        StringBuilder html = new StringBuilder(doc2.Body.OuterHtml);
        String substitution = "<span style='background-color: rgb(255, 255, 0);'>" + element.OuterHtml + "</span>";
        html.Replace(element.OuterHtml, substitution);
        doc2.Body.InnerHtml = html.ToString();
    }

Читает только первую ссылку. я не знаю, что с этим происходит ..

Ответы [ 2 ]

2 голосов
/ 09 января 2012

Этот код выполняется в основном потоке, а не в рабочем потоке из-за вызова Invoke.Так что да, он будет блокировать пользовательский интерфейс при запуске, Speak () требует времени.Использование BeginInvoke не решает эту проблему.

Соберите строки сначала в List<string>, что не должно занимать больше доли секунды.Передайте этот список работнику, чтобы он говорил.

Использование SpeakAsync () также может сработать, избегая цепочки и упрощая прерывание речи, но будет сложнее отслеживать, где вы находитесь на странице.Четко решенный итератором, кстати, просмотрите ключевое слово yield в своей любимой книге по языку C #.

1 голос
/ 09 января 2012

Запрещается изменять пользовательский интерфейс из потока, отличного от потока диспетчера, связанного с элементом управления, который вы пытаетесь изменить.Вам нужно будет использовать Control.BeginInvoke , чтобы выполнить обновление из другого потока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...