0

I'm looking for an efficient way to do a process (Process1) every N times of time period, as for example every 2 weeks or every 6 months, being the integer value (N) defined by the user who can enter any integer value from the keyboard.

For now, I have the code doing the ‘Process1’ as should when this process needs to be done every 1 week or every 1 month, so it is working perfectly until this point.

For the N time periods part, I’m trying with something based on the next logic with these if-statements and a counter that are inside a predefined loop that is already working as should and can't be modified, so the only part I need to get is the one of what would be inside the loop.

…
private int  N;          //Integer number defined by the user
private int  i = 1;      //Counter
…

// loop
{
…
     If ( N == 1 )       
     {
                         /*
                            N = 1 would be the default value with which: 1 week (every 1 week), 
                            or 1 month (every 1 month),…
                         */
     
        …
        //do Process1    /*
                            This part is already working as should because is not even needed to specify
                            there is a `N == 1` to have Process1 to be done every week or every month, but
                            I put it as logic guide of how I think it would be the process flow. 
                         */
     }
    
     else if ( N > 1  &&  i < N )
     {
                i++;     //Increment the counter
     }

    If ( i == N )
    {
        …
        //do Process1
        i = 1;
    }
…
}
…

The efficiency issue I can see with this kind of logic is that if N = 40 (40 weeks for example), or a number even larger due a typing error, then the code for ‘i++’ process will be done 40 times before to reach the point to do Process1, and that’s the reason why I was wondering if there is a more efficient or simplified way to maybe just specify something similar like:

…
//To specify Process1 to be done every N weeks, like every 2 weeks, or any other N int number.
If ( ( Period.DayOfWeek == DayOfWeek.Friday) *N )
{
…
    //do Process1
}
…
//To specify Process1 to be done every N months, like every 6 months, or any other N int number.
If ( ( Period == Time.Month) *N )
{
…
    //do Process1
}

Some clarifications:

Please note this is needed to work with historical data and there is no need to change the current way with which Process1 is done.

Also, because the requirements, it can’t be done with libraries in general or with external programs, neither in a way to filter the historical data with some other ways.

What can be used is only basic code like if-statements, DateTime/DayOfWeek, counters and these kind of “basic code”, among other things because it is a very simple situation that doesn’t need any special “feature”. Please think that everything is working as should 100% perfect. And the only part that can be modified is the DateTime/DayOfWeek part in order to be able to just change the current way: “do somthing every week/month” to the required way: “do somthing every N weeks/months”. Only that. Thank you for every comment trying to provide alternatives, but it's a very basic situation and only the DateTime part can be modified.

Thank you in advance for the help!

adiario
  • 53
  • 1
  • 6
  • 1
    It's unclear to me how your current code is related to a recurring task. Do you plan to just make the code sleep for a day? Do you assume the machine won't be restarted for months and your process will just wait and the counter will slowly accumulate? This is not how scheduled tasks work. Depending on your operating system, there would be an API specifically designed for these type of tasks, e.g. Windows Task Scheduler. – Rotem Mar 04 '22 at 17:23
  • Depending on your requirements, you may want to consider using a library. One opensource library that comes to mind is [Quartz.NET](https://www.quartz-scheduler.net/). – quaabaam Mar 04 '22 at 17:33
  • Thank you for the comment @Rotem. I would like to clarify the code is to work with saved historical data, to obtain information about what happened in certain past period of time, for example what results had certain process for every 2 months during 2021, etc. etc. so there is not any kind of problem about what you mention about if the code will be "sleeping" for days/weeks/months. Please don't worry about part. So what I need is to know about how to do the part of "N times" as N weeks, N months, ... – adiario Mar 04 '22 at 17:40
  • Thank you for the comment @quaabaam. I think your suggestion would be perfectly valid when the case is to keep running a program for long time periods as weeks or months, but this is not the current situation. I added another comment right above clarifying the code is mainly to be run for historical data, so results are shown almost immediately as soon as the program ends its calculations that normally it takes some seconds and done. – adiario Mar 04 '22 at 17:50
  • @adiario In that case you should show what your data looks like. You can easily filter out elements in your data collection using LINQ based on e.g. what day of the week they are, and/or every Nth element using https://stackoverflow.com/questions/682615/how-can-i-get-every-nth-item-from-a-listt – Rotem Mar 04 '22 at 17:52
  • Thanks @Rotem. I understand you want to help giving alternatives. I really appreciate that but the situation is very simple and there is no need to change the way the code work to do the required process. Please note the code is currently working perfectly and flawless when the case is every 1 week or every 1 month, because is not even needed you want the process to be run every 1 week or every 1 month. So the only part I need is how to specify that instead to do the process every week or every month, then to specify the process needs to be done every N weeks or every N months. Only that part. – adiario Mar 04 '22 at 18:03
  • As far as I understand that is the suggestion I gave. Without clarification on your part I don't think I can help much more. – Rotem Mar 04 '22 at 18:19
  • If you will do this 1 time in a month (or week) you should not let this process run the rest of the month (or week). Windows had scheduled tasks, Linux has a crontab, which are both perfectly able to do a job once a month (or once a week), or at whatever interval needed. – Luuk Mar 04 '22 at 18:28
  • Thanks @Rotem. I added some notes at the end of the main post to try to clarify some details. What I need is simpler of what can image and because the requirements it can’t be use external libraries, or other ways to filter the data, or external programs to schedule a task. Please think that everything is working as should 100% perfect. And the only part that can be modified is the `DateTime/DayOfWeek` part in order to be able to just change “do this every week/month” to “do this every N weeks/months”. Only that my friend. It's a very basic situation and only the DateTime part can be modified. – adiario Mar 04 '22 at 18:31
  • LINQ isn't an external library, it's an integrated part of c#. You can still do it without it the code would just be more verbose. I think what's missing is what is the type of `Period`? – Rotem Mar 04 '22 at 18:34
  • How do you think you are going to deal with month? Some month have 30 days, others 31, (let's forget Februari). – Luuk Mar 04 '22 at 18:59
  • Thanks @Rotem. I’ve been doing updates to the main post and I had a typing mistake (already corrected). The situation is the solution can’t be done with libraries in general. Could you please give me a guide about how to do this only working with the `DateTime` part without touching anything else? For example, actually the code has a part `If (Period == Time.Month && periodMonth == true)` then `do Process1`. That does the process every month perfectly. So now what I need is a way about how to specify in the `DateTime` part that now it has to be done every **N** months instead of every month. – adiario Mar 04 '22 at 19:02
  • Thanks @Luuk. C# works that part without to specify anything about if the month has 30-31-28-29 days. With something like `If (Period == Time.Month)` C# understand that you are talking about a whole moth period independently of the days a specific month has. So every time the date start with day 1 of a new month then the code recognizes it's a new month. I don’t know about the internal logic about how this works but the true is at least with C# you don’t have to worry about these details. My situation is only about how to do a certain process every N weeks or every N months, as every 5 weeks. – adiario Mar 04 '22 at 19:11

0 Answers0