1

I have create one file which call total-cost.txt and I want to compare two time which is current time and time after added minutes.

I have tried and this is my code

private void OverwriteText()
{
    DateTime dn = DateTime.Now;
    DateTime now= dn.AddMinutes(2);

    if (dn > now )
    {
        dn = now;
        string txt = Convert.ToString(TotCostLong);
        using (FileStream fs = new FileStream("total-cost.txt", FileMode.Truncate))
        {
            using (StreamWriter writer = new StreamWriter(fs))
            {
                writer.Write(txt);
            }
        }
    }
}

private void timer1_Tick(object sender, EventArgs e)
{
    OverwriteText();
}

In my ideas, if the current time is reached the time which added by 2 minutes it will overwrite the textfile.

For example, current time is 11.30 and after that add 2 minutes into current time which is 11.32. After reached 11.32 the file will overwrite.

If have any ideas or solution provided, I have much appreciated it.

timmebee
  • 89
  • 1
  • 2
  • 12
Kim
  • 33
  • 7
  • So `now` is _then_ and `dn` is _now_ and if _now_ is later than _then_ a few microseconds later then make them both _then_? Don't wait, don't check again, just see if time has drifted _backwards_ by two or more minutes. Better variable names would be a start, e.g. `now` and `targetTime`. – HABO Dec 06 '19 at 03:31
  • @HABO Based on your comment, I no need to waste time to do If statement? straight now = then , then overwrite the file? – Kim Dec 06 '19 at 03:38
  • 1
    @Kim, can you please provide more context on the task. From code you provided this condition is never true, because every time you call `OverwriteText()`, you'll capture current time, add 2 minutes and then compare them - it will be always `false`. Do you need to override file in 2 minutes after `OverwriteText()` is called? Or there is some timer? – fenixil Dec 06 '19 at 04:10
  • @fenixil You are right. I want to every 2 miniutes or 1 hours to overwrite the text file by comparing the time . And there is timer for every second to call OverWriteText( ) and i will add to it in my code. Sorry to you, if bring any inconvenient. – Kim Dec 06 '19 at 04:18
  • @Kim did you consider just to set timer to 2 minutes instead of checking time every second? Are there any limitations for that? – fenixil Dec 06 '19 at 04:28
  • @fenixil Yup, I have used the timer to set 2 minutes and is work fine, but i have to try with another solution by some reason. Did you have any ideas to do that by comparing the current time and time after add minutes. – Kim Dec 06 '19 at 04:35
  • `but i have to try with another solution by some reason` - what are the reasons? – Fabio Dec 06 '19 at 20:57

3 Answers3

1

The Simplest thing you can do to achieve what to you want is, you should update your timer interval to 2 minutes, then it will tick after every 2 minutes and you don't need to check anything just overwrite the file.

var timer = new System.Threading.Timer(
    e => OverwriteText(),  
    null, 
    TimeSpan.Zero, 
    TimeSpan.FromMinutes(2)
);

private void OverwriteText()
{
   string txt = Convert.ToString(TotCostLong);
   using (FileStream fs = new FileStream("total-cost.txt", FileMode.Truncate))
   {
       using (StreamWriter writer = new StreamWriter(fs))
       {
           writer.Write(txt);
       }
   }
}
Vaibhav J
  • 1,316
  • 8
  • 15
  • what if `OverwriteText()` throws an exception ;) ? Would you mind to put a comment/update answer or at change code, so that @Kim does not shot his leg? – fenixil Dec 06 '19 at 04:35
  • @fenixil i throw an idea now it is up to him how he takes it, it is not possible to write entire code here. anyway i like your comment "shot his leg". – Vaibhav J Dec 06 '19 at 04:38
  • I know the solution by changing the time interval, but in my situation cant be used. Anyway, thank you for the solution. – Kim Dec 06 '19 at 04:40
  • @Thinker unfortunately your idea is very error prone. It would be nice to provide a context or rise a concern in the answer. I understand that devs learn things the best when production is on fire, but I believe it is important to share a knowledge too. – fenixil Dec 06 '19 at 04:47
  • @fenixil error prone? i don't think so, otherwise Microsoft has not built this functionality. It is the same what you have suggested in your answer but in short. – Vaibhav J Dec 06 '19 at 04:52
  • @Thinker , unfortunately not quite, @Kim is using `System.Windows.Forms.Timer` which dispatches exception in the UI thread and you can just continue or register global UI error handler. Check how System.Timers.Timer, System.Threading.Timer and System.Windows.Forms.Timer handle exceptions, there are different flavors of that. – fenixil Dec 06 '19 at 04:58
  • Microsoft does not protect you from making mistakes or writing dangerous code, you application may crash because of many reasons. Your option is the most dangerous and that's why I encourage you to put at least a note, so that readers which will review answer and copy code will be aware about this threat. – fenixil Dec 06 '19 at 05:10
0

you can compare like following instead of add minutes to it

 DateTime now= DateTime.Now;

 if((before - now).TotalMinutes > 2) {}

 DateTime before = now;

if you want to try somethng different there is reactive extension for it using observable. https://github.com/dotnet/reactive and require Rx.NET

Observable.Interval(TimeSpan.FromMinute(2), DispatcherScheduler.Current)
     .Subscribe(
        x =>
        {
          string txt = Convert.ToString(TotCostLong);
          File.WriteAllText("total-cost.txt", txt);
        });
phonemyatt
  • 1,287
  • 17
  • 35
0

As you explicitly ask to help with the time comparison option, check answer below. However, this is wasting resources and I'd recommend to use timer for that, just set its interval to 120000ms and you are done

To make your code work, you need to 'remember' current time instead of replacing it on every method call. Just put it to private field and reset it once file is written.

private DateTime _lastWriteTime = DateTime.Now;

private void OverwriteText()
{
    if ((DateTime.Now - _lastWriteTime).TotalMinutes > 2)
    {
        string txt = Convert.ToString(TotCostLong);
        File.WriteAllText("total-cost.txt", txt);
        _lastWriteTime = DateTime.Now;
    }
}

private void timer1_Tick(object sender, EventArgs e)
{
    OverwriteText();
}

Every second (interval you call OverwriteText()) you'll get current time and substract from it time when you write file last time _lastWriteTime. Result is TimeSpan, so this value will grow every second and once it is larger than 2 minutes you'll enter if block.

fenixil
  • 2,106
  • 7
  • 13
  • Thanks for your solution, I will try it. :) – Kim Dec 06 '19 at 04:43
  • what if OverwriteText() throws an exception ;) ? Would you mind to put a comment/update answer or at change code, so that @Kim does not shot his leg? Same applies to you. – Vaibhav J Dec 06 '19 at 04:53
  • @fenixil is work fine, very pleasure to have this solution. But I do not understand how it work by using the formula DateTime.Now - _lastWriteTime .Total Minutes > 2. Can you please to explain a litter to me? – Kim Dec 06 '19 at 04:55
  • @fenixil Thanks for your explanation, it much helpful to me. – Kim Dec 06 '19 at 06:10