Load multiple XML files to TreeView controls using multithreaded
Translation: Qiufeng original code: loadingXMLINTVMTCODE.ZIP
In many cases, the programmer needs to use multi-threaded to develop applications, users can operate data or other work in the front desk, which is loaded with some files in the background program, and this process does not affect the front desk. In this article, I will tell how to load multiple files through multiple threads.
In this example, we will study such a thing, read multiple XML files and display them through TreeView. We can complete it through the database, but XML files are used in order to maintain examples.
You will notice that we have two XML files that are placed together.
The program user interface is as follows:
The FileDisplayer class is used to display the above form. Forms include some button: Browse button, run the button, terminate the press and exit the button. The application can end the running of the entire program by clicking to exit. When you click Browse, you will open a file selection dialog box to load an 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)
{
String filename = OpenFiledialog1.FileName;
// If the file extension is XML, select success
IF (Filename.Length! = 0) && (Filename.endSwith ("XML")))))))
{
FILENAME_BOX.TEXT = filename;
}
}
}
Once a file is selected, the user can read file data by clicking run. The result of the display is as seen in TreeView above. The main purpose of this article is to perform multi-threaded readers. Terminate the task of exiting the execution pressing the button.
Now we are used to all user interface controls, let us study other parts. You can pay attention to our code in your code (you are below):
Private thread queuemonitorthread; // Define a thread to monitor queues
Private requestQueue Req_queue; // Load the loaded file information (file name)
Private bool m_babort; // Control QueuemonyMonitorThread through this flag
Private threadeventdeLegate ontreeViewElement; // Asynchronous agent call, switch thread to update TreeView
In the Requestqueue.cs file we define a RequestQueue class, he is a queue to store file name data. In this example, the queue is set to 5. Therefore, the queue can put five file names inside. There is a logic in the add method. If the file is successfully returned 1, if the failure (the queue is full) returns 0; the Remove method is used to move the queue head index, if the head index, the queue is empty; getFile method It is used to get the top of the queue. If you return 0, the setsize method is used to reset the volume of the queue. If the original data will be thrown away (here the author uses an array to simulate the ring queue, set the capacity to re-instantiate an array); iSempty method To determine if the queue is free. Note: You can also use the Queue class under the System.Collections named space.
When you click on the run button, the program gets the file name from the Get Path Text box and adds it to the Fileinfo structure (very strange here the author's structure just a string). Finally, the structure is added to the queue. The QueuemonitorThread thread will scan a queue half a second half.
Private void ProcessButton_Click (Object Sender, System.Eventargs E)
{
Fileinfo f = new fileInfo ();
f.fname = this.filename_box.text;
// If the queue is full, wait for the queue to add Filinfo when you have time.
While (REQ_QUEUE.Isempty ()! = 1)
{
IF (req_queue.isempty () == 1)
Break;
Thread.sleep (200);
}
REQ_QUEUE.Add (f);
}
Below is the constructor of the inheritance form.
Public FileDisplayer ()
{
InitializationComponent ();
REQ_QUEUE = New Requestqueue ();
/ / Set the queue capacity of 5
REQ_QUEUE.SETSIZE (5);
/ / The default monitoring thread has not terminated
m_babort = false;
// Instance will monitor threads
QueuemonyMonitorThread = New Threadstart (QueuemonyMonitorFunc);
QueuemonyMonitorThread.start ();
// Proxy update TreeView, BeginInvoke
OntreeViewElement = New ThreadEventDelegate (PopulatetreeView);
}
Below is the method of execution of the thread.
Public void queuemonitorfunc ()
{
While (True)
{
IF (isabort ()) // determined if the thread jumps out of the loop, end the thread
{
Break;
}
Object o = req_queue.getfile (); // Get files from queue
IF ((o is fileinfo) // is empty
{
FileInfo f = (fileInfo) req_queue.getfile ();
String filename = f.fname;
PARSE (f); // Start a thread processing
REQ_QUEUE.Remove (); // remove the file from the queue
}
Thread.sleep (500);
}
}
Please pay attention to the QueuemonitorThread thread above, he does not deal with the file. Just detection queue, if there is a file where the Parse method is called, the PARSE method generates a thread for each file.
The method is as follows:
Private Void Parse (fileInfo info) {
// Return a thread
Thread T = Parserthread.createthread (New Parserthread.Start (Parsermethod), Info;
T.Start ();
// Blocking call thread
T.join (Timeout.infinite);
}
Below is a class that creates a thread:
Public Class Parserthread
{
// method of agency
Public Delegate Void Start (Object Obj);
// This class is used to resolve ThreadStart can only be designed without a non-return value function.
PRIVATE CLASS ARGUMENT
{
Public Object Obj1; // Used to save file name data
Public START S1;
// Establishing this method is to proxy by ThreadStart,
Public void parse ()
{
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 successfully completed the passage of parameters. Below 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;
}
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;
}
}
/ / Switch the thread to the thread created by TreeView, so that TreeView is updated, but here is asynchronous.
BeginInvoke (ontreeViewElement, New Object [] {this, new threadEventArgs (EMP)});
}
}
}
Catch (Exception Exp)
{
Messagebox.show ("Error ... in Displaying TreeView" Exp.Message);
}
}
The EmpDetails class implements the IEMPDetails interface, used to include data, slightly.
The BeginInvoke method is executed asynchronously, and the PopulaTreeView method is called by 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, used to transmit 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 inside this example is useful for displaying a lot of documents. Another limit here is that once you click on the termination of the button, the monitoring thread will terminate. To enable you to use it needs to be worked again.
I hope some ideas in this article will help you (with parameter call threads and create multithreaded tasks).