Using multithreading to load multiple XML files into the TreeView control

Source: Internet
Author: User
Tags add empty end header sleep string terminates thread
treeview|xml| Multithreading | load | Control In many cases programmers need to use multithreading to develop applications, users can operate data or other work in the foreground, in the background program is loading a large number of files, and this process does not affect the foreground users. In this article, I'll tell you how to load multiple files with multiple threads. In this example, we'll look at one such thing, read multiple XML files and display them through the TreeView. We can do this through the database, but in order to keep the example simple, we use an XML file. You will notice that we have two XML files together with the original code. The program user interface is as follows:
The  filedisplayer class is used to display the above form. The form includes some buttons: Browse the button, run the button, terminate the button, and exit the button. The application can end the entire program by clicking Exit and pressing Newlay. When clicked, a File Selection dialog box opens to load the XML file. Of course you can also enter the full path of the file directly in the text box. private void Selectbutton_click (object sender, System.EventArgs e) {     OpenFileDialog OpenFileDialog1 = new OpenFileDialog ();     openfiledialog1.filter = "All Files (*.*) |*.*| Text Files (*.txt) |*.txt ";     if (openfiledialog1.showdialog () = = DialogResult.OK)   & nbsp;  {         String fileName = openfiledialog1.filename;         //If the file name extension is XML, select Success          if ((filename.length!= 0) && (filename.endswith ("xml"))          {               Filename_box. text=filename;        }    }}  Once selectedSelect a file, the user can click to run to read the file data. The results shown are as seen in the TreeView above. The main purpose of this article is to give readers a way to perform multithreading. Terminates the task that the button uses to quit execution.   Now that we've gotten used to the various user interface controls, let's look at the other parts. You can note in the code that we have written some of the following code (as follows): private thread queuemonitorthread;//defines a thread that is used to monitor queues for private requestqueue req_queue;// Put the loaded file information (filename) private bool m_babort;//through this sign to control queuemonitorthreadprivate threadeventdelegate ontreeviewelement;// Asynchronous proxy invocation, toggle thread to update treeview in the RequestQueue.CS file we define a Requestqueue class that is used by a queue to store file name data. In this example, the capacity of the queue is set to 5. So the queue can put up to five file names inside. There is a logic in the Add method that if the add file successfully returns 1, if the failure (the team is full) returns the 0;remove method used to move the queue header index, if the header index waits for the tail index that queue is empty; The GetFile method is used to get the first item in the queue. If you return 0 for null, the SetSize method is used to reset the capacity of the queue, and if the original data is invoked, it is thrown away (the author uses an array to simulate the loop queue, the set capacity will instantiate an array), and the IsEmpty method is used to determine whether the queue is empty.   NOTE: You can also use the queue class under the System.Collections namespace.   When you click on the Run button, the program gets the filename from the Get Path text box and adds it to the FILEINFO structure (it's strange that the author's structure just saves a string). Finally, the structure is added to the queue. The Queuemonitorthread thread scans the queue in half a second. private void Processbutton_click (object sender, System.EventArgs e) {     FileInfo f = new FileInfo () ;     F.fname=this.filename_box. Text;    ////If the queue is full then add filinfo     while (Req_queue.isempty ()!=1)       {         if (req_queue.isempty () = 1)                break;          Thread.Sleep (m);    }     Req_queue.add (f);} The following is the constructor for the inherited form. Public Filedisplayer () {     InitializeComponent ();     req_queue = new Requestqueue ();    //Set queue capacity to 5     Req_queue.setsize (5);     //default monitoring thread does not terminate      M_babort = false;    //instance will monitor the line of sight       queuemonitorthread = new Thread (new ThreadStart (Queuemonitorfunc));     Queuemonitorthread.start ();    //Agent update treeview,begininvoke     OntreeviewelemeNT = new Threadeventdelegate (Populatetreeview);}   Below is how the thread executes. public void Queuemonitorfunc () {     while (true)      {          if (Isabort ())//To determine whether the thread jumps out of the loop, end thread          {               break;         }         Object o = Req_queue.getfile ();//Get file from queue          if ((o  is FileInfo))//queue is null           {              FileInfo f = ( FileInfo) Req_queue.getfile ();              string filename = f.fname;              Parse (f) ;//start a thread processing               req_queue.remove ()//Remove file from queue          }         Thread.Sleep (+);    } Note the queuemonitorthread thread above, and he does not process the file himself. Simply detects queues, and calls the parse method if a file exists, and the parse method generates a thread for each file processing. The contents of the method are as follows: private void Parse (FileInfo info) {              //Returns a thread      thread t = parserthread.createthread (new Parserthread.start (Parsermethod), info);     T.start ();    //Blocking call thread      t.join ( Timeout.infinite); The following is the class that created the thread: public class parserthread{    //Proxy generation parameter method      public delegate void Start (Object obj);    //The class is designed to resolve that ThreadStart can only be represented without parameters and no return value function.      Private Class argument     {          public Object obj1;//to save file name Data          public Start s1;         //This method is established to represent,         public void Parse () by ThreadStart.          {               S1 (OBJ1);         }    }    //Create a return thread.      public static Thread CreateThread (Start s, Object arg1)      {          Argument arg = new Argument ();         Arg.obj1 = arg1;         Arg.s1 = s;          thread t = new Thread (new ThreadStart (arg.parse));         Return t;    }} Below is the Parsermethod method:public  VOID Parsermethod (Object obj) {     FileInfo finfo = (FileInfo) obj;     process _xml ((Finfo.fname));} If you look at the CreateThread method of the Parserthread class, the Parsermethod method above is very clear. We have successfully completed the transfer of parameters. The following is the Process_xml method:public  void Process_xml (String name) {     try     {          XmlDocument doc = new XmlDocument ();          String fname = name;         doc. Load (fname);         XmlNodeList nlist1;          XmlNodeList nlist2;         XmlNodeList nList;          Nlist=doc. getElementsByTagName ("Empdataset");         for (int m =0;m          {              XmlElement element_main = (XmlElement) Nlist.item (m);//emp_table               nList1 = Element_main. ChildNodes;//emps              for (int k =0;k               {                    XmlElement element_fchild = ( XmlElement) Nlist1.item (k);                    nList2 = Element_fchild. ChildNodes;                    iempdetails emp = new Empdetails ();                    if (m_babort)                    {                        return;                   }                    for (Int J =0;j                    {                        XmlElement child_element = (XmlElement) Nlist2.item (j);                        if (Child_Element. Name = = "emp_id")                        {                             Emp.empid = System.Convert.ToInt32 (child_element. InnerText);                        }                        if (child_element. Name = = "Emp_name")                         {                             Emp.empname = Child_Element. innertext;                      }                        if (child_element. Name = = "Emp_address")                         {                             emp.empaddress = Child_Element. innertext;                       }                        if (child_element. Name = = "Emp_city")                         {                             emp.empcity = child_element. innertext;                       }                        if (child_element. Name = = "Emp_state")                         {                             emp.empstate = Child_Element. innertext;                       }   &NBsp;                    if (child_element. Name = = "Emp_pin")                         {                             Emp.emppin = Child_Element. innertext;                       }                        if (child_element. Name = = "Emp_country")                         {                             emp.empCountry = Child_ Element. innertext;                       }                        else if (child_element. Name = = "Emp_email")                         {                             Emp.empemail = Child_Element. innertext;                       }                    }                   //Toggle threads to the TreeView created to update the TreeView, but this is asynchronous.                    BeginInvoke (Ontreeviewelement, new object[] {This, new Threadeventargs (EMP)});              }        }     }     catch (Exception exp)      {          MessageBox.Show ("error...in displaying TreeView" +exp. Message);    }}empdetails class implements the Iempdetails interface, which is used to contain data, slightly. The BeginInvoke method executes asynchronously, in which the Populatetreeview method is invoked via proxy ontreeviewelement: private void Populatetreeview (object sender, Threadeventargs e) {     iempdetails ex = e.empdetails;     TreeNode n = new TreeNode ("EMP: "+ex.empid";     n.nodes.add (ex.empname);     n.Nodes.Add ( ex.empaddress);     N.nodes.add (ex.empcity);     n.Nodes.Add (ex.empState );     N.nodes.add (ex.emppin);     n.nodes.add (ex.empCountry);      N.nodes.add (ex.empemail);     treeView1.Nodes.Add (n);} The other is the parameter class, which is used to transfer the contents of the XML file: public class threadeventargs:eventargs{     iempdetails _empdetails;      public iempdetails empdetails      {          get{return _empdetails;}     }     public Threadeventargs (iempdetails empdetails)       {         this._empdetails = empdetails;     }}  Conclusion: The design in this example is useful for displaying a large number of files. Another limitation here is that once you click the Stop button, the monitor thread terminates. To make it reusable, it needs to be heavy on its application. Hope this article inside of aSome ideas will help you (call the thread with parameters and create multithreaded tasks).

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.