To achieve the following sequence:
//1. Code until this position
//2. Code to run in a new thread
//3. Code that runs after thread is started
Just do the following:
Use the class ParameterizedThreadStart and pass the "code snippet" as an Action as parameter.
An example looks like this:
Create two methods:
public void RunMethodOnThread(Action action)
{
Thread thread1 = new Thread(new ParameterizedThreadStart(ExecuteInThread));
thread1.Start(action);
}
private void ExecuteInThread(Object a)
{
Action action = a as Action;
action.Invoke();
}
After that you can use the following call in your code, by passing a so called delegate function as an Parameter:
//1. Code until this position
RunMethodOnThread(delegate
{
//2. Code to run in a new thread
});
//3. Code that runs after thread is started
I know the solution seems a little bit complex, but by going this way you can achieve a very good reuse of your code and it is really easy to use it, especially if you have a lot of small "code snippets" that should run in a new thread.
First of all we have to load the complet XML structures (root of XML Shema) in a variable.
Then wo do a search for the "font"
tag and "/font"
tag and replace it with an empty string.
public void resetfontsize()
{
// XPath to tho root of the XML Shema
string xml_data = this.MainDataSource.CreateNavigator().SelectSingleNode("/my:Befund",NamespaceManager).InnerXml;
// set the Index of the searcher = 1
int nextindex = 1;
//if the search index greater than 0 --> make the search
while (nextindex > 0)
{
//serach for open tag font
nextindex = xml_data.IndexOf(" 0)
{
//search for close tag
int nextklammer = xml_data.IndexOf(">", nextindex);
string replstring = xml_data.Substring(nextindex, nextklammer - nextindex + 1);
//replace the result with empty string
xml_data = xml_data.Replace(replstring, "");
}
}
xml_data = xml_data.Replace("", "");
this.MainDataSource.CreateNavigator().SelectSingleNode("/my:Befund", NamespaceManager).InnerXml = xml_data;
}
First we start to prepare the form:
1) Create a new infopath form
2) Rename the top element to “Root”
3) Add a “Repeating table” element with three columns to the infopath form
4) Name the group element “Details”
5) Name the repeating table element “RepTable”
6) Type a name for each element (”FieldA”, “FieldB”, “FieldC”)
7) In the repeating table properties within the tab “Data” do not allow the user to insert and delete rows. You must uncheck the checkbox (default is checked). We do that because we want to add automatically rows to the repeating table.
We want to load data to the repeating table when you click a button. It is your choice to make an on load event or react on some input to fill the table
1) Add a button to the form
2) On right click go to “Button properties”
3) Write on the label “Load”
4) Write as ID “LoadRepData”
5) Click edit form code. When you do that InfoPath will automatically add the necessary reference to the code behind file to react on the button
6) click event.
At this point we can start to code the InfoPath form. If you close the editor you can reach it if you click on the “Tools” menu “Programming” -> “Microsoft Visual Tools for Applications”.
Bind the navigator to the elements. Iterate the loop and fill the fields
XPathNavigator xPathNavi = MainDataSource.CreateNavigator();
XPathNavigator details = xPathNavi.SelectSingleNode(”/my:Root/my:Details”, NamespaceManager);
XPathNavigator repTable = details.SelectSingleNode(”my:RepTable”, NamespaceManager);
XPathNavigator node;
int counter = 0;
// iterate loop to fill table
for (int i=0; i<1; i++)
{
node = repTable.Clone();
node.SelectSingleNode(”my:FieldA”, NamespaceManager).SetValue(”FieldA - Row ” + i.ToString());
node.SelectSingleNode(”my:FieldB”, NamespaceManager).SetValue(”FieldB - Row ” + i.ToString());
node.SelectSingleNode(”my:FieldC”, NamespaceManager).SetValue(”FieldC - Row ” + i.ToString());
details.AppendChild(node);
counter += 1;
}
Because that we clone the row we need to remove the last row:
// delete a specific range of nodes
XPathNodeIterator rows = details.Select(”my:RepTable”, NamespaceManager);
XPathNavigator first = details.SelectSingleNode(”my:RepTable[1]”, NamespaceManager);
XPathNavigator second = details.SelectSingleNode(”my:RepTable[” + Convert.ToString(rows.Count - counter) + “]”, NamespaceManager);
first.DeleteRange(second);
We decided to develop the program in Microsoft .Net C# 2003. The startup of the pc’s were realized by wake on lan. Wake on lan is a message format. It contains eight times the mac adress of the network interface from the pc which should be started. This message is then send via a udp broadcast to his network interface which has to provide a wake on lan service.
To track the status of the clients we used UDP. The clients had to send a specific package (which also contains specific information) every couple of minutes, so that the server new that the client is online. For sending commands to the client the server established a TCP connection to the clients. This was used for example for the remote monitoring. For handling the clients the server implements a class for accepting incoming connections and managed each connection in a single thread. One challenge was to create no race conditions with the implementation of multi threading.
The client software was established by a windows service, which had the advantage to run in background and to get started with windows. Also the server program provides statistical evaluations for the administrator (E.g. internet usage, cpu usage,…) via diagramms.