CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14

Hybrid View

  1. #1
    Join Date
    Apr 2008
    Posts
    6

    Getting an object from a different thread

    Ok, I've done some googling, searched these forums, but I couldn't find the answer to my problem. So here it is:
    I've got a function in a class that creates a new thread which creates an XMLDocument object and downloads data into it. After it is finished it should somehow pass on that XMLDocument to the main thread (that runs the class, so to speak) so I can get data from it.
    So I don't have to access any data while the thread is running, if that makes a difference (and I think it does, from what I've seen so far).

    So far the only code I've got working is the code without sharing the XMLDocument when finished, and it is this:

    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Text;
    using System.Xml;
    using System.Net;
    using System.IO;
    using System.Windows.Forms;
    using System.Threading;
    using System.Drawing;

    namespace Lolcats
    {
    class LolcatsRss
    {

    private string url = "http://this/is/my/rss/url";

    XmlDocument xmlDoc;
    Thread webThread;

    public LolcatsRss()
    {
    Thread webThread = new Thread(new ThreadStart(getRss));
    webThread.Start();
    }

    public void getRss() {
    XmlDocument _xmlDoc = new XmlDocument();
    _xmlDoc.Load(url);
    }
    }
    }


    I've tampered with some delegates, but nothing that didn't throw a theading-related exception, so obviously not the right way. Who can enlighten me?

  2. #2
    Join Date
    Apr 2008
    Posts
    6

    Re: Getting an object from a different thread

    Quick fix (I can't edit my post (?)):
    System.Windows.Forms was only there to be able to show a messagebox every now and then, it's not there for any serious purpose and will be removed again, so this is not some kind of control or form, might that not have been clear already.
    System.Windows.Drawing is there because there's some image-processing to be done once the XmlDocument is downloaded.

  3. #3
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Getting an object from a different thread

    One way to do this is to create an event in the LolcatsRss class and a public XmlDocument property.

    Users of this class would then subscribe to the event.

    When the thread completes loading the document, if fires the event.

    In the event handler, the user of the class would using the public property to access the xmldoc.

  4. #4
    Join Date
    Jul 2006
    Posts
    297

    Re: Getting an object from a different thread

    Well Arjay suggested what I was about to explain. Since its a rather complicated solution and hard to explain unless you already know how to work with events I made a little program to show you what hes talking about.

    Hope this example helps, i tried to document it the best I could so you would understand whats going on. It works for me, basically it loads an xml document from a thread and populates a ListBox from the nodes it read from the xml document.
    Attached Files Attached Files

  5. #5
    Join Date
    Apr 2008
    Posts
    6

    Re: Getting an object from a different thread

    The thing is: that's not really what I want to do.
    I have 2 threads within the rss-class, one 'main' thread that's running the rss-class, and my other thread that downloads the XML. When the XML-downloading is done, I want the main thread (that's running the rss-class) to have access to the XmlDocument to get some values from it. The XmlDocument does not need to be shared between classes, only between the two threads within that class.

  6. #6
    Join Date
    Jul 2006
    Posts
    297

    Re: Getting an object from a different thread

    If you already have a thread that the rss-class is running in then why do you need a second thread to download the xml? You're not blocking the UI or anything. You can't just return a object from a thread when the thread is done. You have to fire some event letting the other thread know that the resources are available to use. As soon as the thread that downloads the xml starts, the thread calling it continues. It can't wait for the thread (if it did you wouldn't be using a thread) to return some value.

  7. #7
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: Getting an object from a different thread

    Monalin is right - why use a thread in the first place. If you have thread A blocking until thread B has loaded the xml document, why not just load the xml document in thread A ?

    Code:
    The XmlDocument does not need to be shared between classes, only between the two threads within that class.
    I think you're confused. A 'thread' is not a member of any class - it is an execution path. As such it can (and does) go everywhere and anywhere, access any data it pleases just as the main thread can.

    Threads are not related to classes, it's just in .NET you have a thread class to manage them and enable you to refer to them.

    Darwen.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  8. #8
    Join Date
    Apr 2008
    Posts
    6

    Re: Getting an object from a different thread

    Quote Originally Posted by darwen View Post
    Monalin is right - why use a thread in the first place. If you have thread A blocking until thread B has loaded the xml document, why not just load the xml document in thread A ?

    Code:
    The XmlDocument does not need to be shared between classes, only between the two threads within that class.
    I think you're confused. A 'thread' is not a member of any class - it is an execution path. As such it can (and does) go everywhere and anywhere, access any data it pleases just as the main thread can.

    Threads are not related to classes, it's just in .NET you have a thread class to manage them and enable you to refer to them.

    Darwen.
    Yeah, some poor choice of words there on my behalf. The 'main' thread runs both the UI and loads the rss-class. Then the rss-class spawns another thread to download the XML. When that is done, the thread that runs both the GUI and the rss-class should be notified and presented somehow with the XmlDocument so it can get some data from the Xml to pass on to the GUI.
    I don't want to invoke controls or anything like that, I want to keep it all separated so it's usable in lots of different projects...

  9. #9
    Join Date
    Jul 2006
    Posts
    297

    Re: Getting an object from a different thread

    Quote Originally Posted by graey View Post
    Yeah, some poor choice of words there on my behalf. The 'main' thread runs both the UI and loads the rss-class. Then the rss-class spawns another thread to download the XML. When that is done, the thread that runs both the GUI and the rss-class should be notified and presented somehow with the XmlDocument so it can get some data from the Xml to pass on to the GUI.
    I don't want to invoke controls or anything like that, I want to keep it all separated so it's usable in lots of different projects...
    By modifying my example code i attached slightly you can do just that. I believe my code does what you're looking for. You just need to tweak it a little to work with your system. The same principles apply.


    "Then the rss-class spawns another thread to download the XML" - DOES IT

    " When that is done, the thread that runs both the GUI and the rss-class should be notified" - DOES IT (via an event)

    " and presented somehow with the XmlDocument so it can get some data from the Xml to pass on to the GUI" - DOES IT

    If you don't understand the code i attached please ask questions. I think using events and callback functions are the only way you can accomplish what you're trying to do. Heres the slightly modified code, just change Form1.cs to this...

    Code:
            public XmlDocument xml = new XmlDocument();
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void populateNames_Click(object sender, EventArgs e)
            {
                // Create a new instance of the names class
                Names myNames = new Names();
    
                // Register the event to fire when we have the xml data
                myNames.PopulateNamesComplete += new PopulateNamesCompleteEventHandler(populateNames_Complete);
    
                // Start the new thread
                myNames.LoadNames();
            }
    
            private void populateNames_Complete(Object sender, PopulateNamesCompleteEventArgs e)
            {
                // When this thread gets called its still running in the other thread so you can't
                // access any of the UI controls on the form unless you do so through a delegate funciton
                // if you just wanted to assign a variable you can still do that without invoking
                // a delegate method.
    
                xml = e.Xml;
    
                // Show the xml just so you know it completed.
                MessageBox.Show(xml.OuterXml);
            }

  10. #10
    Join Date
    Apr 2008
    Posts
    6

    Re: Getting an object from a different thread

    Ah, pass it as part of the event arguments, hadn't noticed that yet, sorry. That indeed seems like it will work exactly like I want it to! I'll change it so that the rss-class is listening to the event itself and then it should work exactly like I want. Thanks!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured