I was doing window services where I'm generating txt files in target path based on some details from a database but I have a problem the service is running too fast!
I was getting same file name in the place of sec variation required so that i can avoid duplicates over there.
code :
using (transactionscope scope = new transactionscope )
{
string nowtime = datetime.now.today.tostring(HHMMss) // it was working fine
}
file should be generates by specific file naming convention !! ex:hhmmss >>> no millisecond
can any one give me exclusive ideas how to face this part?
You can add milliseconds to the filename:
string nowtime = datetime.Now.Today.ToString("HHmmssfff");
See Custom Date and Time Format Strings.
A few notes about the code you posted:
MM is for months, not minutes. You should use lower case mm.
The parameter that ToString takes is a string.
Your code wouldn't compile as it is not correctly cased. Please use code that can be directly used in the future.
Update:
Seeing as you have to use this format, the only other choice is to "slow down" the service.
Adding a:
Thread.Wait(1000);
In the right place (end of loop?) could do the trick.
Alternatively, you can change your code to append to a file if you are still within the same second.
If you are saying that you are creating multiple files with the same name (multiple files in the same second), then I would take the time out to the milliseconds. You can do this with:
DateTime.Today.ToString("HHmmssfff");
The fff denotes the three places to the right of the decimal (thousandths of a second).
Related
I'm working on a tool in c# that will look at dependencies of a task and then filter the MS Project file for those dependencies. It works great in a "regular" MS Project file but I can't figure out how to make it work in an Integrated Master Project file that contains linked source subprojects.
Here's an example of what I'm doing - In this example integrated project file I've tied the milestone "Preliminary Design Review 1" from the "SSI_Example 1" Project as the predecessor to the milestone "Preliminary Design Review 2" in the "SSI_Example 2" Project
What I want to be able to do is loop through the the Task Dependencies object of "Preliminary Design Review 2", and get all of the UIDs of the predecessor dependencies. I'm expecting the UID of the External Dependency.From to return either 6 or 8388614 (The UID values for Preliminary Design Review 1). Given either of those values, I can calculate either the source UID or the master project UID of the task.
However when I actually put this into code and loop through the Task Dependencies of "Preliminary Design Review 2" it returns 107 as the UID for the external predecessor. It seems like 107 is the UID of the "ghost task" that gets created in the source project
Here's an example of the code:
private void TestGetPredessorUID(MSP.Task t)
{
var taskDependencyList = t.TaskDependencies.ToList(); //ToList is an extention I created method
//Get only the Predecessor dependencies of the task
//the GetUID method will always return the UID of the task as it is in the integrated file (source UID + source project seed value)
taskDependencyList = taskDependencyList.Where(tDep => GetUID(tDep.To) == GetUID(t)).ToList();
foreach (var dep in taskDependencyList)
{
/* If the dependency is an external dependency, dep.From it returns the UID of the "ghost task" not the UID of actual task,
even if we are inside the integrated "Master" Project */
Debug.Print(dep.From.UniqueID.ToString());
}
}
Bottom line
Is it possible to get the "real" UID of an external dependency (either as it is in the source project or the master project) without parsing through the Task.Predecessors/Successors or Task.UniqueIDPredecessors/Successors string?
Is it possible to get the "real" UID of an external dependency without
parsing through the Task.UniqueIDPredecessors/Successors string?
The native task unique ID is not exposed anywhere at the task level for the ghost task. However, parsing the UniqueIDPredecessors string can be done using regex.
This pattern will match most predecessor/successor strings:
(((<>\\[^\\]+\\)+)|([A-Z]:|\\)\\([^\\]+\\)+)?\d+([FS]{2}([+-]\d+d)?)?(?=,|$)
I suggest creating a new extension that uses this regex pattern to split up the UniqueIDPredecessors & UniqueIDSuccessors properties in order to get the native UID of the external tasks.
Update regarding duration units & their labels
The regex pattern shown above is looking for lead/lag time expressed in days. It can be modified to find lead/lag times expressed in other units (i.e. minutes, hours, weeks, months, and years) if needed.
Note that the duration unit labels can be formatted on a project-by-project basis from the Advanced tab of the Project Options dialog box:
The settings can be read and changed through code using properties such as DayLabelDisplay and SpaceBeforeTimeLabels.
Before using a regex pattern to match durations in a predecessor string, take note of the user's current settings then change them to match what the regex is expecting and then reset the user's original settings at the end.
One final note: Durations can also be expressed as elapsed time which can be thought of calendar time rather than working time. For example, 9/1/2021 + 30ed = 10/1/2021 whereas 9/1/2021 + 30d = 10/12/2021. Elapsed durations are commonly found in lag times (e.g. a task can start after the concrete has cured). Therefore the regex pattern should include an optional 'e' before the lead/lag time unit.
Here is an untested regex pattern updated to include elapsed durations and all possible units:
(((<>\\[^\\]+\\)+)|([A-Z]:|\\)\\([^\\]+\\)+)?\d+([FS]{2}([+-]\d+e?(min|hr|d|wk|mon|yr)?)?(?=,|$)
I am trying to create a script which does something say show a popup after 1 day. As far as I know I can do this using Thread.Stop or using System.Timers or many other ways. But the problem with each is that the computer has to be continuously running for each of these methods to give desired result at the time I want. Basically I want the script to start with installation of my program, wait for exactly 24 hours, then display a message box. If the computer is switched on at that time i.e. after 24 hours it should show the message box on next start up but only if 24 hours or more have passed. Please help, i am unable to find suitable solution for this. any help will be highly appreciated. I think that it may be achieved by getting the dateTime.Now and putting it in a file, and then compare current system time to the time in file every hour or so, and if 24 hours or more have passed, show the message box. Please help
If a message box is what you need to pop up, then you'll need a Windows Forms application. Here is the workflow of how it'll work:
Application will need to save data, either through a database or to a file.
When the application first loads, it will check either the database or the file for a TriggerDate entry.
If the TriggerDate exists, pull this date and compare it to today's date and time. If the current date and time is past our TriggerDate, display the message box. Recreate the TriggerDate with the current date and time plus 24 hours.
If TriggerDate does not exist, create it, filled with the current date and time plus 24 hours (e.g. DateTime.Now.AddHours(24)).
Use Threading.Thread.Sleep() to sleep for 5 minutes.
Jump to step 3 and repeat.
EDIT
Code will be something like this:
private const string TriggerFile = #"C:\TriggerData\trigger.txt";
private DateTime _triggerDate;
if (!File.Exists(TriggerFile))
{
using (StreamWriter sw = File.CreateText(TriggerFile))
{
sw.WriteLine(DateTime.Now.AddHours(24));
}
}
using (StreamReader sr = File.OpenText(TriggerFile))
{
_triggerDate = DateTime.Parse(sr.ReadToEnd());
}
while (true)
{
if (DateTime.Now >= _triggerDate)
{
MessageBox.Show(#"Alert!");
using (StreamWriter sw = File.CreateText(TriggerFile))
{
sw.WriteLine(DateTime.Now.AddHours(24));
_triggerDate = DateTime.Now.AddHours(24);
}
}
System.Threading.Thread.Sleep(60000*5); // Sleep for 5 minutes
}
You may not want to do while(true). You way want to implement a way to get out of the program.
If I understand correctly, what you can use is a way to save the "start date". You can save the start date of the timer and read the value from your script, that way you can calculate if 24 hours or more has passed since the moment you assigned a value to the start date. You can use a simply TXT file to save the value.
I see two ways of achieving this :
Easy way (but not strictly related to C#) is to use the task scheduler and create a task that will run your C# program every 24 hours. One way to do this from an installer would be to use the SchTasks.exe tool. This method allows you to just exit the program after your work is done without having to explicitely wait for the next run.
Harder way: Create a Windows Service, which is a program specifically designed to run permanently on the host computer. These programs are slightly more technical to write though. You can find more explanations about services here. However, you may not want to take this route as service cannot display user interfaces like popups.
How can I format the Timestamp data that is printed when you set the TraceOutputOptions = TraceOptions.Timestamp?
Im getting something like:
Timestamp=41329240725 (real value that was written on the output text file)
EDITED:
I want something like 10:22:34.32938. How shoud I configure the TextWriterTraceListener to achieve that?
Do you really want to log the time that the message was written? If so, you want to use TraceOptions.DateTime. Note, that according to MSDN, the time is written as UTC.
If you want more control over the format of the time (including if you want it to be expressed in something other than UTC), then you will probably have write your own custom TraceListener, or find one that will do what you want.
One useful add on for System.Diagnostics is Ukadc.Diagnostics. With it you can easily add custom formatting to your log messages (similar to what you can do with log4net and NLog).
Here are some other links to answers that I have provided in the past to logging questions that you might find useful:
When should I use Tracing vs Logger.NET, Enterprise Library, log4net or Ukadc.Diagnostics?
When do I need more than one TraceSource in code?
According to this page
http://msdn.microsoft.com/en-us/library/a10k7w6c.aspx
TraceOptions Timestamp returns the number of ticks, so to convert ticks into time you need to do:
DateTime date = new DateTime(41329240725);
string FormattedDate = date.ToShortDateString();
however 41329240725, seems a little small for ticks (I'm hoping that was just an example)
well in my database i had a colum for price of one product
i had it as float, my problem is if i saved it since my c# application
as 10.50 .. in a query it returns 10,50 and if i update i get a error
10,50 cant convert to float ... or something so..
and if i saved it as decimal, in queries inside sql management .. are ok..
but in my c# application... i get the same error..
10.50 retuns as 10,50 i dont know why, and how to solved it.. my unique solution is saved it
as varchar...
That's a localisation problem of some sort. 10,50 is the "European" way of writing ten and a half. If you're getting that from your select statements then your database is probably configured incorrectly.
Generally speaking you should use the same type throughout your layers. So if the underlying types in the database are x, you should pass around those data with identical types in c#, too.
What type you choose depends on what you are storing--you shouldn't be switching around types just to get something to "work". To that end, storing numeric data in a non-numeric type (e.g. varchar) will come back to bite you very soon. It's good you've opened this question to fix that!
As others have miraculously inferred, you are likely running into a localization issue. This is a great example of why storing numbers as strings is a problem. If you properly accept user input in whatever culture/localization they want (or you want), and get it into a numeric-type variable, then the rest (talking to the DB) should be easy. More so, you should not do number formatting in the database if you can help it--that stuff is much better placed at the front end, closer to the users.
I think your setting in windows regional and language for decimal symbol is wrong.please set it to dot and again test it.
This may help out for temporary use but I wouldn't recommend it for permanent use:
Try making it so that just before you save the file, convert the number to a string, replace the commas with periods (From , to .) and then save it into the database as the string, hopefully it should see that it is in the correct format and turn it into what the database sees as "Decimal" or "Floating".
Hope this helps.
Yep, localization.
That said, I think your pice is being stored on a "money" field in SQLServer (I'm assuming it's SQLServer you're using). If that was a float in the DB, it would return it with a normal decimal point, and not the European money separator ",".
To fix:
Fist DO NO USE FLOAT in your c# code, unless you absolutely require a floating point number. Use the decimal type instead. That's not just in this case, but in all cases. Floating point numbers are binary (base-2), not decimal (base-10), so what you see in the interface is only a decimal approximation of the actual number. The result is that frequently (1 == 1) evaluates as false!
I've run into that problem myself, and it's maddening if you don't know that can happen. Always use decimal instead of float in c#.
Ok, after you've fixed that, then do this to get the right localization:
using System.Globalization;
...
NumberFormatInfo ni = new NumberFormatInfo();
ni.CurrencyDecimalSeparator = ",";
decimal price = decimal.Parse(dbPriceDataField, ni);
Note that "dbPriceDataField" must be a string, so you may have to do a ".ToString()" on that db resultset's field.
If you end up having to handle other "money" aspects of that money field, like currency symbols, check out: http://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx
If you need more robust error handling, either put that decimal.Parse in a try/catch, or use decimal.TryParse.
EDIT --
If you know what culture (really, country), the db is set to, you can do this instead:
using System.Globalization;
...
CultureInfo ci = new CultureInfo("fr-FR"); // fr-FR being "french France"
decimal price = decimal.Parse(dbprice, ci.NumberFormat);
Such problems were faced by me in my Web Apps... but i found the solution like I was fetching my price value in textbox. So I was have database attached with that. So when you attached your database with textbox... When you right click textbox and click Edit DataBinding.... in that you have to provide.... type like in Bind Property..... {0:N2}
This will work only for web apps or websites... not for desktop applications...
Assume I have a String Field in my WinApp like below :
public string UsingTheApplicationFrom =
"Not Yet";
Now , I wanna to change the value of the field forever, in first running of my application. e.g : UsingTheApplicationFrom = "Friday, January 21, 2011";
Is it possible in C# WinApp ?
Could you please guide me?
Edit:
I don't wanna use Database or file or Registry or something else.
You are looking for "a type of security for my application that only the first system (that runs the application for the first time) could use my application". I think you mean that each copy of the software you sell may only be installed on one computer at a time.
You have two problems to solve:
How to generate a unique identifier for the computer
How to store the identifier value
You have several options to use for a unique identifier, none of which are great. Be prepared for support requests from customers when they change their computer hardware, when their computer breaks, or when they want to move the software from one computer to another. A decent-looking method to compute a unique identifier is this article (mirror link since the code project article is not available).
I would recommend just storing this identifier as a string in the app.config file (using Properties.Settings, start at this link for more information). It will be visible in plain text, but how would an unlicensed user know what value to change it to for their machine when it looks like "4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9"? If it doesn't match direct them to your website/telephone for support.
You still have the problem of deciding when to set this value -- I would advocate for setting it as part of an installer instead of saving it the first time the program is run, since then you still have a problem to determine when the program is first run. The installer might need some sort of registration code and a method to communicate with a central licensing server. (Yes, this does get complicated -- how determined do you think people might be to hack your licensing?)
I am taking a guess, but by "always" I think he means "forever". You could easily create a key in the App.config of your application and populate it on the first run.
<add key="UsingTheApplicationForm" value="Not Yet"/>
On first run, update it to -
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["UsingTheApplicationForm"].Value = DateTime.Now.ToShortDateString();
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
// Force a reload of a changed section.
ConfigurationManager.RefreshSection("appSettings");
On second run check if the key value is equal to "Not Yet". If it is not, it means that this is not the first run.
I think maybe you want to use DateTime, and particularly, DateTime.Now - as with comments to the question however, I'm not properly sure.
So, something like:
UsingTheApplicationForm = String.Format("{0:dddd, MMMM d, yyyy}", DateTime.Now);
The 'always' part is very confusing though, I'm just going to buy into my own translation, where always = each startup.
I would also conjecture that, given the property/variable name of UsingTheApplicationForm, this value is an indicative field, rather than a descriptive one; for this reason, may just using DateTime.Now without any formatting, or even just a boolean (depends what fits your situation) fit the bill?
Edit:
For information on using this method, or any of the others, along with persisting this data for the next run, see the following question and answers...
Editing app.config in execution time using the same App
I like this way:
http://windowsclient.net/blogs/suryahg/archive/2008/08/11/persist-winforms-application-settings.aspx
There's no way to do it with nothing more than a string object, but you can create a simple object that does it:
public class ApplicationInfo
{
private ApplicationStartTime()
{
this.StartTime = new DateTime().Now;
}
public DateTime StartTime
{
get; private set;
}
public Create()
{
return new ApplicationStartTime();
}
}
I haven't compiled that, so there may be a minor syntax error or two. You would invoke it like so:
var applicationInfo = ApplicationInfo.Create();
Debug.WriteLine(applicationInfo.StartTime.ToString());
In your program.cs or main entry point for the program declare a public static datetime.
when the program is first run you can set the date time and access it in future.
public static Datetime m_StartDate = DateTime.now;
public static void Main(args)
{
m_StartDate = DateTime.Now;
}
then in your other forms (assuming you added the code to Program.cs)
txtStartTime.Text = Program.m_StartDate.toString();