【问题标题】:BackgroundWorker in WPF not working [duplicate]WPF中的BackgroundWorker不工作[重复]
【发布时间】:2014-01-14 09:42:51
【问题描述】:

我有一个导航网页的按钮。我试图将导航放在后台工作人员中,但它不能导航。如果我把它放在按钮的点击事件中它工作正常。我在 bgw_DoWork 中放置了一个断点,它表明它达到了创建新 wb 对象的目的,但是它跳过了 DoWork 中的其余语句。我想这样做,以便在尝试从网页获取数据时显示加载图像。 webbrowser 对象不是 UI 的一部分,因为用户不需要查看抓取。它只是将信息下载到一个对象中,然后再显示该对象(在 BackgroundWorker 之外)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Reflection;
using System.ComponentModel;
using mshtml;

namespace WPF1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {


        WebBrowser wb;
        private readonly BackgroundWorker bgw = new BackgroundWorker();

        public int i = 0;

        public MainWindow()
        {
            InitializeComponent();
            bgw.DoWork += bgw_DoWork;
            bgw.RunWorkerCompleted += bgw_RunWorkerCompleted;

       }

        private void GetSICData_Click(object sender, RoutedEventArgs e)
        {
            //mainTabControl.SelectedIndex = 1;

            //wb.Navigated += wb_Navigated;
            //wb.LoadCompleted += wb_LoadCompleted;
            //wb.Navigate("http://www.google.com");

            bgw.RunWorkerAsync();

        }

        private void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            wb = new WebBrowser();

            wb.Navigated += wb_Navigated;
            wb.LoadCompleted += wb_LoadCompleted;
            wb.Navigate("http://www.google.com");

        }

        private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("Background Complete");
        }

        void wb_LoadCompleted(object sender, NavigationEventArgs e)
        {

            HTMLDocument doc = (HTMLDocument)wb.Document;
            doc.getElementById("ctl03_TextBox1").innerText = "2334882";

            wb.LoadCompleted -= wb_LoadCompleted;
            wb.LoadCompleted += wb_LoadCompleted_2;

            doc.getElementById("ImageButton1").click();

        }

        void wb_LoadCompleted_2(object sender, NavigationEventArgs e)
        {
            MessageBox.Show("It Worked!");
        }

        void wb_Navigated(object sender, NavigationEventArgs e)
        {

        }

    }
}

【问题讨论】:

  • 您不能在后台线程中控制 UI 元素
  • 有没有办法创建一个不属于 UI 的 webbrowser 对象?
  • @user3175176 如果您不想将 WebBrowser 显示为 UI 的一部分,您可能不应该使用它,相反,您可能应该使用完全旨在下载网站的其他类内容而不显示它们。
  • 谢谢你的服务。我会调查的。我只是想,因为 WebBrowser 是内置的,所以它最容易使用。您对可以使用哪些其他类有什么建议吗?
  • @EricJ.,虽然这似乎与您的“可能重复”帖子一开始非常相似,但问题作者的问题和 cmets 似乎说他们实际上只是想在后台下载一个网页。因此,这个问题虽然措辞有些拙劣,但却是关于一个不同的主题。也许问题作者可以编辑以使其更清晰,您可以删除您的近距离投票?

标签: c# wpf webbrowser-control backgroundworker


【解决方案1】:

听起来你真正想要的是WebClient Class。您可以使用它的多种方法将整个网页下载为文件或string。最好的部分是您也可以异步执行此操作,因此这一切都会自动在后台线程上发生。

在使用这些异步方法时,您需要处理相关的Download...Completed 事件来检索结果。来自 MSDN 上的DownloadStringCompletedEventHandler Delegate 页面:

public static void DownloadStringInBackground2 (string address)
{
    WebClient client = new WebClient ();
    Uri uri = new Uri(address);

    // Specify that the DownloadStringCallback2 method gets called 
    // when the download completes.
    client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(
DownloadStringCallback2);
    client.DownloadStringAsync (uri);
}

private static void DownloadStringCallback2 (Object sender, 
DownloadStringCompletedEventArgs e)
{
    // If the request was not canceled and did not throw 
    // an exception, display the resource. 
    if (!e.Cancelled && e.Error == null)
    {
        string textString = (string)e.Result;

        Console.WriteLine (textString);
    }
}

查看 MSDN 网站上的 WebClient.DownloadStringAsync MethodWebClient.DownloadFileAsync Method 页面了解更多信息。

【讨论】:

    【解决方案2】:

    您不能在后台线程上创建 UI 控件,在这种情况下您不需要这样做,因为无论如何您需要的所有 WebBrowser 方法都是异步执行的...

    WebBrowser.Navigate

    异步导航到指定 Uri 处的文档。

    顺便说一句,在加载WebBrowser 控件后不要忘记使用Navigate 方法,因此请使用IsLoaded 检查或从Loaded 事件调用导航...

    【讨论】:

      【解决方案3】:

      某些 UI 操作需要在 UI 线程上调用。试试看

          private void bgw_DoWork(object sender, DoWorkEventArgs e)
          {
              wb.Navigated += wb_Navigated;
              wb.LoadCompleted += wb_LoadCompleted;
      
              wb.Dispatcher.Invoke(() =>
              {
      
                  wb.Navigate("http://www.google.com");
              });
          }
      

      【讨论】:

      • 如果你只调用 BGW 中的 UI 线程,那么首先使用 BGW 是没有意义的。
      • 是的,你是对的。我只是想说明一点,但应该更多地关注示例代码。无论如何,WebClient 听起来是个更好的主意。
      猜你喜欢
      • 2011-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多