如何实现异步。在.NET中完成外部使用事件?

时间:2012-02-10 17:29:49

标签: c# .net

我有这个简单的项目来获取HTML元素内部数据。这是一个DLL项目。

 public class WebGrabber
    {
        public string URL { set; get; }

        public string Element { set; get; }

        public bool FindByID { set; get; }

        private WebBrowser b { set; get; }

        private mshtml.IHTMLDocument2 doc { set; get; }

        public void GetPageElementInnerHTML(string url, string element, bool findById)
        {
            URL = url;
            Element = element;
            FindByID = findById;

            b = new WebBrowser();
            b.Navigate(url);
            b.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(b_DocumentCompleted);
        }

        void b_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            doc = (IHTMLDocument2)b.Document.DomDocument;

            string result = "<html>";

            IHTMLElement head = (IHTMLElement)((IHTMLElementCollection)doc.all.tags("head")).item(null, 0);

            result += "<head>" + head.innerHTML + "</head>";

            if (null != doc)
            {
                foreach (IHTMLElement element in doc.all)
                {
                    if (element is mshtml.IHTMLDivElement)
                    {
                        dynamic div = element as HTMLDivElement;   

                        if (FindByID)
                        {
                            string id = div.id;

                            if (id == Element)
                            {
                                result += "<body>" + div.IHTMLElement_innerHTML + "</body></html>";

                                break;
                            }
                        }
                        else
                        {
                            string className = div.className;

                            if (className == Element)
                            {
                                result += "<body>" + div.IHTMLElement_innerHTML + "</body></html>";

                                break;
                            }
                        }
                    }
                }
            }
            doc.close();      
        }
    }

我需要的是将访问实施为字符串结果变量。

因此可以从其他项目中异步获取此变量

也许我需要一些GetResult();方法?....

我怎么做?

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以将eventhandler作为参数传递,然后在类库中的app no中使用结果o只需传递回调并在下载完成后调用。

我是新来的,所以我希望我明白你想要的东西。

传递evnthandler

public void GetPageElementInnerHTML(string url,string element,bool findById,WebBrowserDocumentCompletedEventHandler downloadComplete)

使用委托:

公共类WebGrabber         {

        public string URL { set; get; }

        public string Element { set; get; }

        public bool FindByID { set; get; }

        private WebBrowser b { set; get; }

        private mshtml.IHTMLDocument2 doc { set; get; }

        public delegate void DownloadCompletedDelegate(string result);

        private DownloadCompletedDelegate _downloadedComplete;

        public void GetPageElementInnerHTML(string url, string element, bool findById, DownloadCompletedDelegate downloadComplete)
        {
            _downloadedComplete = downloadComplete;
            URL = url;
            Element = element;
            FindByID = findById;

            b = new WebBrowser();
            b.Navigate(url);
            b.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(b_DocumentCompleted);
        }

        void b_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            doc = (IHTMLDocument2)b.Document.DomDocument;

            string result = "<html>";

            IHTMLElement head = (IHTMLElement)((IHTMLElementCollection)doc.all.tags("head")).item(null, 0);

            result += "<head>" + head.innerHTML + "</head>";

            if (null != doc)
            {
                foreach (IHTMLElement element in doc.all)
                {
                    if (element is mshtml.IHTMLDivElement)
                    {
                        dynamic div = element as HTMLDivElement;

                        if (FindByID)
                        {
                            string id = div.id;

                            if (id == Element)
                            {
                                result += "<body>" + div.IHTMLElement_innerHTML + "</body></html>";

                                break;
                            }
                        }
                        else
                        {
                            string className = div.className;

                            if (className == Element)
                            {
                                result += "<body>" + div.IHTMLElement_innerHTML + "</body></html>";

                                break;
                            }
                        }
                    }
                }
            }
            doc.close();

            _downloadedComplete.Invoke(result);
        }
    }

在APP中

GetPageElementInnerHTML(URL,element,true / false,CompletedCallback);

private void CompletedCallback(字符串结果) {     //你的代码

}

答案 1 :(得分:0)

这是工作代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using mshtml;
using System.Collections;

namespace MyCompany.WebpageGrabber
{
    // A delegate type for hooking up change notifications.
    public delegate void ChangedEventHandler(object sender, EventArgs e);

    public class WebGrabber : ArrayList
    {
        // An event that clients can use to be notified whenever the
        // elements of the list change.
        public event ChangedEventHandler Changed;

        // Invoke the Changed event; called whenever list changes
        protected virtual void OnChanged(EventArgs e)
        {
            if (Changed != null)
                Changed(this, e);
        }

        // Override some of the methods that can change the list;
        // invoke event after each
        public override int Add(object value)
        {
            int i = base.Add(value);
            OnChanged(EventArgs.Empty);
            return i;
        }

        public override void Clear()
        {
            base.Clear();
            OnChanged(EventArgs.Empty);
        }

        public override object this[int index]
        {
            set
            {
                base[index] = value;
                OnChanged(EventArgs.Empty);
            }
        }

        public string URL { set; get; }

        public string Element { set; get; }

        public bool FindByID { set; get; }

        private WebBrowser b { set; get; }

        private mshtml.IHTMLDocument2 doc { set; get; }

        public void GetPageElementInnerHTML(string url, string element, bool findById)
        {
            URL = url;
            Element = element;
            FindByID = findById;

            b = new WebBrowser();
            b.Navigate(url);
            b.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(b_DocumentCompleted);
        }

        void b_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            doc = (IHTMLDocument2)b.Document.DomDocument;

            string result = "<html>";

            IHTMLElement head = (IHTMLElement)((IHTMLElementCollection)doc.all.tags("head")).item(null, 0);

            result += "<head>" + head.innerHTML + "</head>";

            if (null != doc)
            {
                foreach (IHTMLElement element in doc.all)
                {
                    if (element is mshtml.IHTMLDivElement)
                    {
                        dynamic div = element as HTMLDivElement;

                        if (FindByID)
                        {
                            string id = div.id;

                            if (id == Element)
                            {
                                result += "<body>" + div.IHTMLElement_innerHTML + "</body></html>";

                                break;
                            }
                        }
                        else
                        {
                            string className = div.className;

                            if (className == Element)
                            {
                                result += "<body>" + div.IHTMLElement_innerHTML + "</body></html>";

                                break;
                            }
                        }
                    }
                }
            }
            doc.close();

            this.Add(result);
        }
    }
}

以下是我们称之为代码的代码:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
     WebGrabber g = new WebGrabber();

     g.GetPageElementInnerHTML("http://www.google.com/web/guest/home", "portlet-borderless-container", false);

     g.Changed += new ChangedEventHandler(g_Changed);            
}

void g_Changed(object sender, EventArgs e)
{
    var html = ((WebGrabber)sender)[0];            
}