|
|
You have two choice:
1. Create a function that will generate a string that will contain the xml. This method is the fastest and the most simple way to do it:
public class CClub
{
int m_id;
string m_name;
public string GenerateXml()
{
return
"<Club ID=\"" + m_id.ToString() + "\">\n" +
"<Name>" + m_name + "</Name>\n" +
"</Club>\n";
}
}
2. Use XmlDocument as told:
public class CClub
{
int m_id;
string m_name;
public void ReadXml(XmlElement element)
{
m_id = Convert.ToInt32(element.GetAttribute("Club"));
foreach (XmlNode node in element.ChildNodes)
{
if (node.NodeType == XmlNodeType.Element &&
node.Name == "Club")
{
m_name = node.InnerText;
}
}
}
public void WriteXml(XmlNode parentNode)
{
XmlElement element = parentNode.OwnerDocument.CreateElement("Club");
parentNode.AppendChild(element);
element.SetAttribute("Club", m_id.ToString());
XmlElement elementName = parentNode.OwnerDocument.CreateElement("Name");
element.AppendChild(elementName);
elementName.InnerText = m_name;
}
}
The departement class should look like this:
public class CDepartment
{
CDepartmentInfo m_departmentInfo;
CClubs m_clubs;
CTeachers m_teachers;
public void ReadXml(XmlDocument element)
{
foreach (XmlNode node in element.ChildNodes)
{
if (node.NodeType == XmlNodeType.Element)
{
switch (node.Name)
{
case "DepartmentInfo":
m_departmentInfo = new CDepartmentInfo();
m_departmentInfo.ReadXml(node as XmlElement);
case "Clubs":
m_clubs = new CClubs();
m_clubs.ReadXml(node as XmlElement);
case "Teachers":
m_teachers = new CTeachers();
m_teachers.ReadXml(node as XmlElement);
}
}
}
}
public void WriteXml(XmlDocument document)
{
m_departmentInfo.WriteXml(document);
m_clubs.WriteXml(document);
m_teachers.WriteXml(document);
}
}
modified on Saturday, November 29, 2008 4:22 PM
|
|
|
|
|
Cool, solution, thanks darkzangel!
regards,
George
|
|
|
|
|
You can use XMLSerialization to do this. It makes your code more cleaner than creating XML using XMLDocument .
All you need is to create types for representing DepartmentInfo, Club and Teacher. It could be something like the following
public class DepartmentInfo
{
public DepartmentInfo(int id,string location,string type) {
this.Id = id;
this.Location = location;
this.Type = type;
}
public DepartmentInfo() {
}
[XmlAttribute("Id")]
public int Id { get; set; }
public string Location { get; set; }
public string Type { get; set; }
}
public class Club
{
public Club(int id,string name) {
this.Id = id;
this.Name = name;
}
public Club() {
}
[XmlAttribute("Id")]
public int Id { get; set; }
public string Name { get; set; }
}
public class Teacher
{
public Teacher(int id,string name,string major) {
this.Id = id;
this.Name = name;
this.Major = major;
}
public Teacher() {
}
[XmlAttribute("Id")]
public int Id { get; set; }
public string Name { get; set; }
public string Major { get; set; }
}
Now you need a Department type which has references to all the above shown types.
[XmlRoot("Department")]
public class Department
{
public Department(DepartmentInfo info,Club[] clubs,Teacher[] teachers) {
this.DepartmentInfo = info;
this.Clubs = clubs;
this.Teachers = teachers;
}
public Department() {
}
[XmlElement("DepartmentInfo")]
public DepartmentInfo DepartmentInfo { get; set; }
[XmlArray("Clubs")]
public Club[] Clubs { get; set; }
[XmlArray("Teachers")]
public Teacher[] Teachers { get; set; }
} You can serialize the Department class to get the specified XML. Here is how you do in a console application.
static void Main(string[] args) {
Club[] clubs = { new Club(200, "Football"), new Club(201, "Basketball") };
Teacher[] teachers = { new Teacher(300, "Thomas", "Algorithm"), new Teacher(301, "Zhou", "Linear Programming") };
Department department = new Department(new DepartmentInfo(100,"San Jose", "Computer Science"), clubs, teachers);
XmlSerializer serializer = new XmlSerializer(typeof(Department));
serializer.Serialize(Console.Out, department);
Console.Read();
} This method works well and your code will look cleaner. But serialization is performance costly as it uses reflection to get details of the type. Manually writing XML using XMLTextWriter or XMLDocument will give you better performance than this. Choosing the method is completly depends on your situation.
Hope this helps
|
|
|
|
|
Thanks Navaneeth!
I like your solution!
regards,
George
|
|
|
|
|
Hello All ,
I have one question... Does anybody know where I can download a copy of the Microsoft Visual C# User Manual. The one that comes with the IDE (Vis. Studio) is crap, it has broken links throughout the whole thing, and even when I choose to view online help it still has broken links. Is there a downloadable version of the C# full documentation? I only want C#.
j.t.
|
|
|
|
|
At least MSDN Express library is here[^]. There may also be other separate downloads on MSDN.
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|
|
BTW: That IS the user manual.
|
|
|
|
|
Thank you both for your help I apologise if I came across as really rude in my original post, I only just realised as I re-read my original post.
Regards,
j.t.
j.t.
|
|
|
|
|
|
string pattern = @"((https?|ftp|gopher|telnet|file|notes|ms-help) //)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]*)"
Ahsan Ullah
Senior Software Engineer
MCTS 2.0
|
|
|
|
|
Thank you both for your answers and code though I only have one problem now, where would I put that code you just gave me? Or, how would I use it?
Regards,
j.t.
j.t.
|
|
|
|
|
A simple example would be:
MatchCollection mathes = Regex.Matches(textContent, "(http://[\w\.\?\&]+\w)");
That would give you a collection of matches for (most of) the URLs in the text. Each match contains information about where in the string it was found and the actual URL that was found.
Now, you would use your mad google skillz to find a more advanced regular expression for matching an URL.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
you could also have a look at boost regex - it comes with some examples of parsing url's
'g'
|
|
|
|
|
I'm currently working on a c# project that need winsock in it. WebClient wasn't enought powerfull for my kind of application. So, I writed from scratch all the code to get all thing in my project with a custom webclient. Everything work fine, but I want to improve my code. One of my problem is a function that read byte from the recv function (recv is a c++ winsock function) and then send it to a stream to eventually get an array of byte (byte[]). If you take a closer look to my code, you will see that I copy twice the data. The first time, I make the convertion from byte* (IntPtr receiveBuff) to byte[] and then, I copy again those data to the stream with mem.Write(). I will like to only to it once. Doesn't any body know a better way to do this so I only have to make one copy of my data?
[DllImport("Ws2_32.dll")]
public static extern int recv(SOCKET s, byte* buf, int len, int flags);
public unsafe byte[] RecvAsBytes()
{
MemoryStream mem = new MemoryStream();
int receivedLen;
IntPtr receiveBuff = Marshal.AllocHGlobal(1024);
byte[] receiveBuff2 = new byte[1024];
while ((receivedLen = recv(socket, (byte*)receiveBuff, 1024, 0)) != 0)
{
Marshal.Copy(receiveBuff, receiveBuff2, 0, receivedLen);
mem.Write(receiveBuff2, 0, receivedLen);
}
Marshal.FreeHGlobal(receiveBuff);
return mem.ToArray();
}
|
|
|
|
|
Hi,
the way I usually transfer large amounts of data between a managed (C#) app and some unmanaged (C) code, is as follows:
1. have the managed code allocate a buffer of sufficient size; it could be a byte array in your case.
2. Use GCHandle class to first pin it down, then obtain a pointer to it.
3. Pass the pointer to the native code to get it read and/or written to.
4. Upon return, free the GCHandle and start using the buffer in the managed world.
In summary: no extra copies are made, and Marshal and MemoryStream classes are avoided.
Hope this helps.
|
|
|
|
|
It didn't help that much. Actually, I wasted more time trying to understand why I should use GCHandler instead of Marshal.AllocHGlobal, lol.
I finally figured out a much better way to do that. The only problem if it's problem is that I still use MemoryStream. The reason why I still use it is because I don't have any idea of the size of the received data. This function is used to receive both: html code and image data. The image size can be as large as 1Mb and my application is multithread. So think about that, allocating a 1Mb each time I want to receive data! I want to optimize my algo and make it as strong as I can, so it's a no no. There is still an another way to go with a pool of 1024 bit buffer and a stack, but this will need much more code and time to develop. Maybe one day... But for now, here is my improved code:
public unsafe byte[] RecvAsBytes()
{
MemoryStream mem = new MemoryStream();
int len;
byte[] buffer = new byte[1024];
fixed (byte* ptrBuffer = buffer)
{
while ((len = NativeImport.recv(socket, ptrBuffer, 1024, 0)) != 0)
mem.Write(buffer, 0, len);
}
return mem.ToArray();
}
|
|
|
|
|
Hi,
1.
your code contains two copy operations that add to the RAM footprint and the CPU load:
first you copy data from buffer to mem, then from mem to the final byte array.
(I checked with Reflector: MemoryStream.ToArray creates a whole new array and copies all the data)
2.
there is no need for a memory stream at all. You could:
- create a list of byte arrays;
- allocate a new byte[1024] array inside the while loop, and add these buffers to the a list;
- when that while loop finishes, add together all the sizes of the partial buffers, allocate a new byte[] of total size, then copy each partial buffer directly into the final buffer. You might use Array.Copy to do that, again inside a loop (I suggest a foreach).
Doing so eliminates half of the copy operations without costing more RAM footprint.
3.
Do you really need the possibly huge single byte array as a result? if not, you could forgo all copying. You might return the list of partial byte arrays, or an object that allows to enumerate the data. It all depends on the consumer of RecvAsBytes().
4.
If you really want the total byte array: if the data is originating from a web server, you may know the total size of the data beforehand; have a look at WebResponse.ContentLength; so you could allocate the final array at once, and fill it in your existing while loop.
5.
BTW: in that case you also can get a data stream directly (WebResponse.GetResponseStream). If your data is not coming from a WebResponse object, maybe you should consider modeling it after WebResponse.
6.
Your "fixed" statement and the GCHandle I suggested basically serve the same purpose; your solution is quite acceptable; the main difference is GCHandle does not require the "unsafe" switch, fixed does.
Cheers.
|
|
|
|
|
From what I understand, if a multi-threaded process runs on a single-processor CPU then the process will take advantage of "time-division multiplexing." Does time-division multiplexing offer any real performance advantages in this setup? Are there any specific use cases where this setup would have clear advantages and ROI over a single-threaded process?
|
|
|
|
|
The answer is: it depends (TM)
Using multithreading on a single CPU will provide a better "parallel" feel of your application, because the OS will try to assign CPU time to all threads as equally as possible (according to their priorities). But don't overdo it - using too many threads on a single CPU can yield to lots of costly context switches, which in turn will actually decrease performance of your app.
So use threads cautiously on a single CPU and do some profiling if you feel that it doesn't run as smoothly as you expected.
regards
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Member 3919049 wrote: Does time-division multiplexing offer any real performance advantages in this setup?
No. It simply means that the CPU runs one thread at a time, and by switching threads often it appears as threads run simultaneously.
With a few threads there is little difference from running a single-threaded process. If you have a lot of threads the overhead of switching threads will be greater, leaving less CPU time for actual work.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
Member 3919049 wrote: if a multi-threaded process runs on a single-processor CPU
Do you know anybody that still only has one single core?
Nick
----------------------------------
Be excellent to each other
|
|
|
|
|
Yes, many, many, many, many businesses and a ton of home users.
I just built my first multi-core machine THIS WEEK.
|
|
|
|
|
|
I know that, in general, threads run in the context of a process and share memory.
Processes run independently of each other and don't share memory.
Does .NET support the ability for different processes to share memory? It doesn't seem like this would be a very good architecture to implement but is there any use case where this would need to be done. If so then does .NET support this or provide workarounds to support this?
|
|
|
|
|