|
SeptimusEjjog 151576 wrote: I want to write some trace messages to a text file.
I suggest you research logging APIs instead.
|
|
|
|
|
BitLogger is on the proverbial radar.
If there is one thing more dangerous than getting between a bear and her cubs it's getting between my wife and her chocolate.
|
|
|
|
|
One aspect of your scenario, abstracted to a general level, is: how to prevent recursion when method #3 ... invoked by method #2 ... invoked by method #1 ... "may" call method #1 ? imho, while you state your scenario is not recursive, reading your list of possible calls suggests it might be potentially recursive, and that you are doing something to prevent recursion.
Another, more probable, interpretation is: that you do have a non-recursive scenario here: because the methods are invoked as a result of the user's asynchronous direct actions on interface elements at run-time, so a call to any method may be followed by a call to any other method. I believe that if you wish to represent that as a "tree:" in a "literal" way: there could only be one "root node" (the first method called). Of course nothing "stops" you from treating every call to any given method as a "root node:" it's your choice.
But, on the basis of the information you supply, I can only guess at what's going on in the code, and whether you do, or don't, have to deal with potential recursion.
In general, I would "react" to code that implements an elaborate mechanism to prevent recursion, because it has to, as poorly designed code, most likely in need of re-factoring.
Have you considered, as an alternative to using an integer "level count" variable (which I don't see as "that big a deal"), using something like a .NET Stack data-structure when tracing is activated, and then pushing something onto the stack when any method is called; and, then, parsing that stack when you wish to create your text log-file ?
In WinForms writing tab characters into a text-file is simple "\t\tTwo tabs," and these could be shown at run-time in a WinForms TextBox if its 'AllowTabs property is set to 'true. Or, a WinForms RichTextBox can give you much finer-grained control over tabs, by setting them in code.
good luck, Bill
Google CEO, Erich Schmidt: "I keep asking for a product called Serendipity. This product would have access to everything ever written or recorded, know everything the user ever worked on and saved to his or her personal hard drive, and know a whole lot about the user's tastes, friends and predilections." 2004, USA Today interview
|
|
|
|
|
Bill, thanks your valuable input. My example I gave was quite coarse and didn't truly reflect what my code looks like but I wanted to eliminate the possibility of recursion. That method "C" for example is a lower level chunk of code that reassembles and decrypts some bytes from the device and once that's done, it could call another method to handle some endianess flip/flops on some bits of data.
For expediency, the trace output data is written with a couple of spaces as it's useful to me to separate the higher "what's been requested" from "what's being done". Once the whole thing is bedded down and running smooth (as well as molasses running uphill could ever run smooth ) then the detailed tracing will fade away but will still be configurable as an option.
My particular need to is to find out why a stable deep-rooted socket one moment is like tumbleweed the next.
If there is one thing more dangerous than getting between a bear and her cubs it's getting between my wife and her chocolate.
|
|
|
|
|
Hi, I'm glad you found my response useful in some way.
It seems to me you have at least two separate concerns here:
1. "I wanted to eliminate the possibility of recursion." ... that implies to me you do have possible recursion, and, either you have already handled that in some way, or you haven't. I am not sure, from what you've described, whether you have, or have not, controlled possible recursion ... satisfactorily.
2. "why a stable deep-rooted socket one moment is like tumbleweed the next." ... my guess is that could be "framed" as a separate question for this forum, and, if accompanied by a detailed description of what's happening, and what you need to achieve, and how what you are doing now is, possibly, not working, or "fumbling" on "edge-cases:" I'd expect you could get some good answers here. But, not from dolts like me, to whom sockets are mysterious alien entities.
Is it possible that your scenario here includes handling simultaneous multiple streams of incoming data ? Bernard H.'s question, asking whether you are dealing with multi-threading here, is also quite important, imho.
I assume that once you have "trace history" built/working the way you need/want (using a Stack, or Tree, or whatever, data structure), then parsing that trace history, and formatting a text-file output in any way you like, using tabs, spaces, etc., is a minor concern.
Being a "treeview junkie," I use tree data-structures (and, in WinForms, a very powerful 3rd. party TreeView Control, or (from the same 3rd. party), a combination ListView/TreeView Control, whenever possible.
I suppose one could actually write code to, at run-time, using Reflection, to actually modify every method "marked" with some attribute like [TraceThis] to also push an identifying integer onto a stack, but I shudder at the thought of doing that: that would require going into the "world" of ICustomAttributeProvider, and then dealing with issues like those described here: [^], or here [^]. I have not yet done this, and hope to avoid doing it: my guess is the "cost" of doing that would be greater than the cost of parsing the call-stack dynamically.
yours, Bill
Google CEO, Erich Schmidt: "I keep asking for a product called Serendipity. This product would have access to everything ever written or recorded, know everything the user ever worked on and saved to his or her personal hard drive, and know a whole lot about the user's tastes, friends and predilections." 2004, USA Today interview
|
|
|
|
|
Bill, I identified the "tumbleweed problem" a short while ago and I kick myself for not finding it sooner. The device I have the socket connected to demands a ping "keep alive" interval. I have that value in the app config file, say, 1000s for example but my ping thread sleeps for 9/10th of the time, 900 seconds. After the thread wakes up, it waits on a semaphore and usually gets it within a few seconds at most but it depends on the other thread to finish its work. If the other thread only finds a few records in the database it'll finish and release the semaphore allowing the ping thread to get in and ping the device where it then kips for another 900s.
It took a bit of time to go through several 100 lines of trace but on the "random" occasions the socket fell over, there were more records selected. Aha! But it wasn't always consistent. Eventually I saw it. The ping thread woke up and waited on the semaphore with 100s to go. If the other thread took 102s to process all the records, the ping was overdue and the device silently killed the connection so I got an exception the next time I tried to write to it. My bad! I wasn't really displaying enough information. I changed the interval from 9/10ths of the specified time to 1/3rd. It doesn't matter how often the pings take place but each time one is handled, the device resets its timer and ticks on until the next is due. Go overdue and the connection is toasted. I made the ping interval longer, 30m and at 1/3rd intervals I send one every 10m. That 20m period remaining will be more than sufficient for the largest dataset to be processed. In a sense then, I was sailing very close to shore and I scraped my keel on some rocks.
Call me Cap'n Calamity if you will. Think of the Costa Concordia.
If there is one thing more dangerous than getting between a bear and her cubs it's getting between my wife and her chocolate.
|
|
|
|
|
I had to vote this response up: you've got the poet's gift for metaphor !
I sense an excellent article(s) for CodeProject lurks in these dangerous rapids you're shooting the threads of.
yours, Bill
Google CEO, Erich Schmidt: "I keep asking for a product called Serendipity. This product would have access to everything ever written or recorded, know everything the user ever worked on and saved to his or her personal hard drive, and know a whole lot about the user's tastes, friends and predilections." 2004, USA Today interview
|
|
|
|
|
BillWoodruff wrote: I sense an excellent article(s) for CodeProject lurks
Bill, to be honest, it'd take a braver bloke than me to write an article. I've read many of them and quite often you get folks who'll line up your down vote button in their rifle scope and slowly squeeze the trigger. That, I can live with.
Then you get the good folks who'll barf at you because the content isn't deemed appropriate to the context. That I can handle because it's constructive.
There are good folks who'll encourage you and there are good folks who'll appreciate what you do. The rapids are indeed dangerous waters.
It's only once you roll the die do you see what happens.
If there is one thing more dangerous than getting between a bear and her cubs it's getting between my wife and her chocolate.
|
|
|
|
|
You could come close to that by logging each function in its first line ("Calling SomeFunction(params)") and its last line ("Exiting SomeFunction"). Well, that's not yet the nice indentation, but at least you could find out the call stack from the log. For a multithreaded application, logging a thread property additionally (e.g. System.Threading.Thread.CurrentThread.ManagedThreadId) may be useful.
|
|
|
|
|
Bernard, there are five threads involved. I emit the thread id into the trace file after the time stamp and it makes it a breeze to identify which thread is responsible for what message. It's very helpful.
If there is one thing more dangerous than getting between a bear and her cubs it's getting between my wife and her chocolate.
|
|
|
|
|
Hi I have text as an output that is in the following format.
Example install cdb 000
Firstname LastNameNot Started(2) Normal02/09/2013 18:0002/09/2013 23:00426
Example install cdb 000
Firstname LastNameNot Started(2) Normal02/09/2013 18:0002/09/2013 23:00426
Example install cdb 000
Firstname LastNameNot Started(2) Normal02/09/2013 18:0002/09/2013 23:00426
Example install cdb 000
Firstname LastNameNot Started(2) Normal02/09/2013 18:0002/09/2013 23:00426
What im trying to do is to substring/split this text so i can put it in a datagrid or list view.
Idealy I need the text in the following format so I can do this but I am having trouble trying to figure out the c# behind this.
Ideally the text would output as,
Example install
cdb 000
Firstname LastName
Not Started
Example install
cdb 000
Firstname LastName
Not Started
etc, for each entry in the source text.
(2)Normal02/09/2013 18:0002/09/2013 23:00426 (remove this text from the string)
The problem is that I would have to loop through all the text from the source to get this output. But the source text above is not always that length and could contain more entries.
Any ideas on this one?
I would apreciate any help anyone can give.
Thanks
|
|
|
|
|
Probably the best way to parse this (you did't specify if there are seperators between fields!) would be a rather complex regular expression. This expression would have to take into account the possible values in certain columns, such as that "Not Started" column, to server as boundaries that the RegEx parser can use to find other fields, like first and last name.
|
|
|
|
|
Thanks dave,
And I didnt supply if there were seperators as the source text is the format it is supplied in.
Also the firstname/lastname is an example this would actually have someones name.
thanks
|
|
|
|
|
Member 10119837 wrote: And I didnt supply if there were seperators as the source text is the format it
is supplied in.
OK, then the answer doesn't change. If there is no seperator between fields and no distinct column width for each field, String.Split and String.SubString will not help you. RegEx is about the only way you're going to get this done.
Member 10119837 wrote: Also the firstname/lastname is an example this would actually have someones
name.
Says Mr. Obvious. What may not be so ovious is that some people go by one name and others go by more than two, so your going to have to make sure you test those possibilities.
|
|
|
|
|
I'm going to assume, based on what you describe, that you have no control over the "batch" of "entries" to be parsed here. Is that correct ?
The second issue is: to what extent is there any possible variation in the content of each "entry" you need to parse, and re-format ? As Dave pointed out to you, is it possible that the "name field" in each entry could vary, as in: Robert Smith; Robert T. Smith; Robert Thomas Smith; R. T. Smith III; Robert Smith 3rd. ... and so forth.
The extent to which you can establish the "variation" possible in the entries imho is going to determine the complexity of either:
1. creating a RegEx as Dave suggested.
2. taking your "batch" and transforming it into another "batch" in which you have inserted de-limiters so that you can, then, use string.Split.
I would likely write code to transform the original data (file, stream, whatever) and insert delimiters, simply because I am not expert in RegEx, and the C# code I'd write, imho, might be more maintainable, and re-usable. However, I would not doubt that someone like Dave could write a documented RegEx expression of great internal complexity that would be equally maintainable, and re-usable. So your choice may depend on what you are most expert in using now, and, given a need, for other people in the future to update, maintain, re-use, your code what those people are likely to be expert in.
Now, if the data was in XML format, you might be looking at defining an xsd to handle transformation.
good luck, Bill
Google CEO, Erich Schmidt: "I keep asking for a product called Serendipity. This product would have access to everything ever written or recorded, know everything the user ever worked on and saved to his or her personal hard drive, and know a whole lot about the user's tastes, friends and predilections." 2004, USA Today interview
|
|
|
|
|
if there are separators then you typical use split.
split on value, split on line count ,typical of csv file type.
Now, you also can have a file that is fixed length fields..
Split then on field count then you just substing(x,y) out and prob split on line feed.
Now, if your trying to sort data out of something that follows no standard then now your looking at some sort of parsing method.
either reg expressions or loops.
=)
|
|
|
|
|
One of our customers receives an error message while running our application and many other applications on their computers. The error message is in German: "Win32Exception (0x80004005): Fehler beim Erstellen des Fensterhandles" which likely corresponds to "Win32Exception (0x80004005): Error while creating window handle".
Now we are trying to find out how that is caused.
When searching the web, there is a lot of confusion about those "handles". When looking into Windows Task Manager: which column in the Processes tab does correspond to the "correct" type of "handles": "Handles", "User objects", "GDI objects", ... (found all of them)
Or better take Process Explorer, and look at which columns?
And: what's the limit of those handles (system-wide, per application, ...)? (Found numbers from 1000 for the application to 16 million for the system; Process Explorer shows currently some 47000 Handles system-wide on my PC...)
Thanks a lot for trying to help me get rid of the confusion.
|
|
|
|
|
The max number of handles has values as both pre-process and system-wide, depending on the version of Windows you're talking about and the conditions under which it is running. It's not exactly a straight forward answer. Read this[^] for more information.
Truthfully, if you're getting this message, you might want to look at the Task Manager Handles column on the affected machines, not yours. There are cases where software leaks resources and handles, exhausting the system handle pool and causing problems like this. Usually the culprit process will stand out prominently. It's very rare to see a process go over 10,000 handles.
I had a Dell OSI service leak handles years ago, showing over 100,000 handles in that one process alone, before causing Windows to lose it's mind generating all kinds of problems over every other process that was running.
|
|
|
|
|
Thanks for this information.
According to the link you provided, some 16 million handles are allowed, but allocating handles in handle pages may reduce the number.
So things are complicated to analyse: on the custumer's computer, an application used up some 22 thousand handles when our application crashed, but at a different crash that application was below 1000 handles... And even with 22000 handles: that's some 1.5% of available system resources, we will hardly be able to convince the manufacturer of that program that they do something terribly wrong thus causing our application to crash...
By the way, how can an existing window handle be lost? In one case, our application crashed at an Invoke: the window handle did no more exist. A dialog had been opened, a control with its own window handle had been used succesfully; then the user had a break, the computer was locked (session switch event); after unlocking an hour later, the user did something else on the computer before using our program again, and then it immediately crashed due to the missing handle. I do not understand that. We did not Dispose() of it.
And all those problems happen with one single customer only, hundreds other customers never experience such problems (and remote access is not possible here: everything top secret).
|
|
|
|
|
Bernhard Hiller wrote: how can an existing window handle be lost?
Open a handle to an object and never properly close it, then orphan it by letting the variable that was holding the handle fall out of scope.
In a .NET app, that's quite easily done by, say, creating a Graphics object and never calling Dispose on it when your done with. Or by allocating a Font, Brush, Pen, Stream, ... by no means an exhaustive list.
Bernhard Hiller wrote: In one case, our application crashed at an Invoke: the window handle did no more
exist. A dialog had been opened, a control with its own window handle had been
used succesfully; then the user had a break, the computer was locked (session
switch event); after unlocking an hour later, the user did something else on the
computer before using our program again, and then it immediately crashed due to
the missing handle. I do not understand that. We did not Dispose() of it.
I don't have a clue there. You'd have the find out what else is running on the machine, such as virus scanner, and see if you can replicate the problem outside of their environment.
|
|
|
|
|
Hi
i have two forms , first form has a datagrid to show Rows record of table and Second Form is the details of every record in dataGrid , when we double Click the row .
In the Second Form , I need to Update Records . So I check the record ("RegNo") is Duplicate for a specific Year.
Here is My code . But I couldn't Update the Records ...:
-----
try
{
if (txtFname.Text == FnameDataGrid && txtLname.Text == LnameDataGrid
&& txtRegNo.Text == RegNoDataGrid && txtYearReg.Text == YearRegDataGrid)
{
OleDbConnection ocn_Edited = new OleDbConnection(ConnectionStringEdited);
OleDbCommand ocmd_Edited = new OleDbCommand();
ocmd_Edited.CommandText = @"UPDATE RegTable SET FNAME=@p1,LNAME=@p2,
YearReg=@p3,RegNo=@p4,
WHERE YearReg=@g1
AND RegNo=@g2";
ocmd_Edited.Parameters.Clear();
ocmd_Edited.Parameters.AddWithValue("@p1", txtFname.Text);
ocmd_Edited.Parameters.AddWithValue("@p2", txtLname.Text);
ocmd_Edited.Parameters.AddWithValue("@p3", txtYearReg.Text);
ocmd_Edited.Parameters.AddWithValue("@p4", txtRegNo.Text);
ocmd_Edited.Parameters.AddWithValue("@g1", YearRegDataGrid);
ocmd_Edited.Parameters.AddWithValue("@g2", RegNoDataGrid);
ocmd_Edited.Connection = null;
ocmd_Edited.Connection = ocn_Edited;
ocn_Edited.Open();
ocmd_Edited.ExecuteNonQuery();
ocn_Edited.Close();
ocmd_Edited.Dispose();
ocn_Edited.Dispose();
MessageBox.Show(" ... This Table Updated ...");
frmShowGrd frmGrd = (frmShowGrd)Application.OpenForms["frmShowGrd"];
frmGrd.boolEdit = true;
frmGrd.FnameDataGrid_1 = txtFname.Text;
frmGrd.LnameDataGrid_1 = txtLname.Text;
frmGrd.YearRegDataGrid_1 = txtYearReg.Text;
frmGrd.RegNoDataGrid_1 = txtRegNo.Text;
this.Close();
}
else
{
OleDbConnection ocn = new OleDbConnection(ConnectionStringEdited);
strSql =@"SELECT RegNo WHERE RegNo=@s1 AND YearReg=@s2";
OleDbDataAdapter oda_Edited = new OleDbDataAdapter(strSql, ocn);
oda_Edited.SelectCommand.Parameters.Clear();
oda_Edited.SelectCommand.Parameters.AddWithValue(" @s1", txtRegNo.Text);
oda_Edited.SelectCommand.Parameters.AddWithValue(" @s2", txtYearReg.Text);
DataTable dt_Edited = new DataTable();
dt_Edited.Clear();
oda_Edited.Fill(dt_Edited);
if (dt_Edited.Rows.Count > 0)
{
MessageBox.Show("Already Exists!! ");
txtRegNo.Focus();
}
else
{
OleDbCommand ocmd_Edited02 = new OleDbCommand();
ocmd_Edited02.CommandText = @"UPDATE RegTable SET FNAME=@t1,LNAME=@t2,
YearReg=@t3,RegNo=@t4,
WHERE YearReg=@e1
AND RegNo=@e2";
ocmd_Edited02.Parameters.Clear();
ocmd_Edited.Parameters.AddWithValue("@t1", txtFname.Text);
-----
I don't don't where's my Mistake .
Plz Help Me .
Thanks
modified 3-Sep-13 8:16am.
|
|
|
|
|
smh1392 wrote: But I couldn't Update the Records
What does that mean? Do you get an error message? If so, tell us the message. Does the table contain values different from those you expected? Does "first form" still show old values instead of the updated values? Anything else different from what you expected?
|
|
|
|
|
according to the code that I wrote above , I want to check the Value of "RegNo" (preventing duplicate the value of "RegNo" Field ), before Updating , but Always Execute this :
if (dt_Edited.Rows.Count > 0)
{
MessageBox.Show("Already Exists!! ");
txtRegNo.Focus();
}
So my database never Update ...
....
Thanks
|
|
|
|
|
Is there is way to invoke solid edge using c#
Thanks
|
|
|
|
|
|