【问题标题】:WPF TPL WebBrowser Control Error: calling thread must be STAWPF TPL WebBrowser 控制错误:调用线程必须是 STA
【发布时间】:2011-08-11 17:30:17
【问题描述】:

我遇到了以下问题: 我想在后台下载一个带有 WebBrowser Control (WPF) 的网站,然后解析该网站。下载应处于“紧密循环”中。我不需要显示页面。我只需要 HTML 源作为字符串。问题是该站点在加载后会使用 JavaScript 动态添加内容,这就是我使用这种方法的原因。 这实际上应该同时适用于多个网站。

在我的以下代码中有错误:“调用线程必须是 STA,因为许多 UI 组件都需要这个”。

我知道如果我将 TaskScheduler 更改为当前上下文,我不会收到任何错误消息。

但是如何在后台下载 HTML 源代码?

添加 我必须将它添加到例如StackPanel 没有这个添加它不起作用

stackpanel.Children.Add(wb2);

有什么想法吗?

提前谢谢你

private void Button1_Click(object sender, RoutedEventArgs e)
        {Task.Factory.StartNew(
                    () =>
                    {
                        WebBrowser wb2 = new WebBrowser();  // That's where I get the error essage
                        wb2.Source = new Uri(MySite);
                        wb2.LoadCompleted += new LoadCompletedEventHandler(wb_LoadCompleted);

                    }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
            }
        }

void wb_LoadCompleted(object sender, NavigationEventArgs e)
        {
            WebBrowser w = sender as WebBrowser;
            HtmlDocument document = new HtmlDocument(w.Document);

更新

我在 StaTaskScheduler 上尝试过这样的操作,但没有更新 UI

StaTaskScheduler (TPL Extension) and WebBrowser Control WPF - Wrong Thread

谢谢!

【问题讨论】:

  • 我不想给出“答案”,因为这不是我的领域。也许您需要调度您的 LoadedCompleted 内容。我从未使用过 Task 或 WebBrowser,所以这只是一个猜测 :) 在后台加载内容的另一种方法,也是 WPF 方式,是使用 BackgroundWorker。
  • 感谢您的回答。在这种情况下,TPL 应该替换 Backgroundworker 等。我在 WebBrowser wb2 = new WebBrowser(); 处收到错误消息

标签: c# wpf multithreading browser task-parallel-library


【解决方案1】:

WebBrowser 已经是异步的,尽管我相信它在 UI 线程上执行脚本。

如果你想把它拆分成一个真正独立的线程,你可以使用STAThreadScheduler。听起来您希望每个网站都有一个 (STA) 线程。

【讨论】:

  • 感谢您的快速回答。我以前从未听说过的 STAThreadScheduler ......我是初学者......你的第一句话是否意味着它已经完成了我想要它做的事情,而无需我添加 TPL 代码? Control 不需要在 ui 线程上执行任何操作。我稍后将解析内容添加到网格中。它只是在后台执行任务,而不会中断任何其他活动
  • 正确。 WebBrowser 将在后台下载网页并在完成后引发LoadCompleted 事件。除非WebBrowser 在 UI 线程上执行大量脚本代码,否则 TPL 不是必需的(我不确定它是否会或者脚本代码是否也会在后台运行)。
  • 谢谢,我还有 2 个额外的问题:我必须将控件添加到 StackPanel 或类似的东西才能使其正常工作。因此,如果我需要 20 个网站,我必须添加 20 个控件。我必须将它添加到 XAML 代码中还是有办法解决它。第二个是:我可以在下载时阻止某些图像或类似的东西以加快进程。就我而言,有时需要很长时间才能加载整个站点,但我不需要整个站点。提前谢谢你
  • 您可以在运行时添加控件。我不知道第二个问题的答案;我建议您在 SO 上打开另一个问题。
  • 谢谢,但为什么我必须将它添加到 RootLayout。否则它对我不起作用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多