-1

I have created a thread in my c# application. its code is given below.

[WebMethod]
public void start()
{
    Thread thread = new Thread(new ThreadStart(WorkThreadFunction));
    thread.Start();
}
[WebMethod]
public void stop()
{
    Thread thread = new Thread(new ThreadStart(WorkThreadFunction));
    thread.Abort();
}
public void WorkThreadFunction()
{
    try
    {


            TimeZone zone = TimeZone.CurrentTimeZone;
            DateTime dt = DateTime.Now.AddHours(12);
            dt = dt.AddMinutes(30);
            TimeSpan offset = zone.GetUtcOffset(DateTime.Now);
            String s = "insert into tb_log(timestamp) values('" + dt + "')";
            Class1 obj = new Class1();
            string res = obj.executequery(s);


    }
    catch
    {
    }
}

When I run this code the value enters only at one time into the table. I need to execute this thread at 1 min intervals throughout the day, week and year. How to make this possible? Also correct me if the code which I had written is correct or not. I'm new to threads in c#. So someone please help me out. Thanks and Regards..

njnjnj
  • 978
  • 4
  • 23
  • 58
  • 1
    See `System.Threading.Timer`. – L.B Mar 06 '14 at 11:20
  • 2
    For these kind of time-triggered jobs i would highly recommend looking into http://www.quartz-scheduler.net/ or some other similar library. Prevents you from reinventing the wheel and can save a lot of work ;-) – BatteryBackupUnit Mar 06 '14 at 11:25
  • @BatteryBackupUnit Can you please show me a sample code of doing it using quartz. I don't know how to do it. I new to multi threading.. – njnjnj Mar 06 '14 at 11:38
  • @TeeJay Quartz features examples, start with this one: http://quartz-scheduler.org/documentation/quartz-2.x/examples/Example1 – BatteryBackupUnit Mar 06 '14 at 11:41
  • How will this code be run? Will it be hosted by IIS or will it be inside a windows service? – Scott Chamberlain Mar 06 '14 at 13:51

4 Answers4

1
public WebServiceClass : WebService
{
    private boolean terminated = false;
    private boolean running = false;

    [WebMethod]
    public void start()
    {
        if (running)
        {
            //Already Running!
        }
        else
        {
            running = true;
            terminated = false;
            //Start a new thread to run at the requested interval
            Thread thread = new Thread(new ThreadStart(WorkThreadFunction));
            thread.Start();
        }
    }

    [WebMethod]
    public void stop()
    {
        //tell the thread to stop running after it has completed it's current loop
        terminated  = true;
    }

    public void WorkThreadFunction()
    {
        try
        {
            DateTime nextLoopStart = DateTime.Now;
            while (!terminated)
            {
                TimeZone zone = TimeZone.CurrentTimeZone;
                DateTime dt = DateTime.Now.AddHours(12);
                dt = dt.AddMinutes(30);
                TimeSpan offset = zone.GetUtcOffset(DateTime.Now);
                String s = "insert into tb_log(timestamp) values('" + dt + "')";
                Class1 obj = new Class1();
                string res = obj.executequery(s);    

                while (DateTime.Now < nextLoopStart)
                {
                    System.Threading.Thread.Sleep(100);
                }    
                nextLoopStart += new TimeSpan(0,1,0);
            }
            //Reset terminated so that the host class knows the thread is no longer running

        }
        catch (ThreadAbortException)
        {
            //LogWarning("INFO: Thread aborted");
        }
        catch (Exception e)
        {
            //LogError("Error in Execute: " + e.Message);
        }
        finally
        {
            running = false;
        }
    }
}
James
  • 9,774
  • 5
  • 34
  • 58
  • Will this not run continuously? How do you abort the thread? Will it not remain in memory and each call starts a new thread? – Peter Smith Mar 06 '14 at 13:35
  • If this is hosted inside IIS the service will stop running after a bit as IIS cylces its AppPool. – Scott Chamberlain Mar 06 '14 at 13:50
  • @PeterSmith I thought the idea was for it to run continuously. The thread will exit cleanly when terminated is set to true, and each call to start will check if there is already a running thread first – James Mar 06 '14 at 13:56
  • @ScottChamberlain, IIS will terminate long running threads? would have to call out to an external process in that case. Another question for another day – James Mar 06 '14 at 13:58
  • IIS will terminate all applications in the pool when its application pool recycles, it will not restart the application until the first person re-connects to the program after the idle period. – Scott Chamberlain Mar 06 '14 at 14:00
  • @ScottChamberlain This implies it might [leave it running](http://stackoverflow.com/questions/5630420/does-recycling-the-iis7-application-pool-kill-any-currently-executing-requests) depending on configuration. It may be it needs to store if it was running or not and resume on restart (or back fill any gaps). I think this is beyond the scope of the question. – James Mar 06 '14 at 14:06
  • @JamesBarrass The question says "I need to execute this thread at 1 min intervals throughout the day, week and year" – Peter Smith Mar 06 '14 at 14:14
  • @PeterSmith Oops just realised, I forgot to put the timing code in. A thread running a section of code periodically will do just that, even if the thread itself runs continuously the effect will be the same – James Mar 06 '14 at 14:59
0

Try the following UPDATED

public class myApp
{   
    public System.Diagnostics.EventLog myEventLog { get; set; }
    private Thread appThread;
    public int TimerIntervalSeconds {get; set;}

    public void Start()
    {

        appThread = new Thread(new ThreadStart(WorkThreadFunction));
        appThread.Start();
    }

    public void Stop()
    {
        if (appThread != null)
        {
            appThread.Abort();
            appThread.Join();
        }
    }
    private void WorkThreadFunction()
    {
        // Loop until the thread gets aborted
        try
        {
            while (true)
            {
                WriteToDatabase();

                // Sleep for TimerIntervalSeconds
                Thread.Sleep(TimerIntervalSeconds * 1000);
            }
        }
        catch (ThreadAbortException)
        {
            myEventLog.WriteEntry("INFO: Thread aborted", System.Diagnostics.EventLogEntryType.Warning);
        }
        catch (Exception e)
        {
            myEventLog.WriteEntry("Error in Execute: " + e.Message, System.Diagnostics.EventLogEntryType.Error);
        }
    }
}

This is the 'complete' class. Call Start to set it off and Stop to end it. Set TimerIntervalSeconds for the frequency you want the event to happen.

I didn't have time initially to give the whole solution.

Peter Smith
  • 5,528
  • 8
  • 51
  • 77
  • can you please tell me how to stop the thread when I want to stop them?? – njnjnj Mar 06 '14 at 11:37
  • @TeeJay change the loop to while(!terminated) and set terminated true when you want to stop, or just call abort on the thread ( you would need to keep a reference to the thread you started ) – James Mar 06 '14 at 11:42
  • @JamesBarrass Can you please explain me what is myEventLog?? It is showing some errors while I coded it.. – njnjnj Mar 06 '14 at 11:53
  • @TeeJay as it's not my code, I don't know but I would guess that it's symbolic of some logging mechanism to store errors, if you don't have a logging mechanism it would be safe to comment it out – James Mar 06 '14 at 11:55
  • @JamesBarrass As you mentioned either I have to call the abort method to stop the thread or I should give the condition as while(!terminated) and set terminated=true when I want to stop it. Which is the best method to stop the thread from the above?? – njnjnj Mar 06 '14 at 11:58
  • @TeeJay I prefer using the terminated approach to avoid using exceptions to control flow. – James Mar 06 '14 at 12:05
  • @JamesBarrass As you said I have coded and I have called the stop method to stop the thread. But the thread is not stopping, its execution. How to stop it?? Please help me fast.. – njnjnj Mar 06 '14 at 12:07
  • @JamesBarrass Do I have to give the boolean terminated=true at the stop method..?? – njnjnj Mar 06 '14 at 12:09
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/49144/discussion-between-tee-jay-and-james-barrass) – njnjnj Mar 06 '14 at 12:15
0

I would use the Timer class in C#. I am not familiar with ASP.NET but I presume the following link would help. http://msdn.microsoft.com/en-us/library/system.web.ui.timer(v=vs.110).aspx

Create an instance of the timer, set the elapsed time in milliseconds and attach your method to the timer's tick event. This method would then be invoked after every x milliseconds.

EDIT: To run the task on a different thread, run it as a task(.NET 4.0 or upwards)

timer.tick += (s,e)=>{

TaskFactory.StartNew(()=> WorkThreadFunction());

};

Please note, exception handling has been ignored for simplicity.

user2822838
  • 337
  • 1
  • 3
  • 13
0

For a simple solution I would use Timer class. Actually there are 3 Timer classes in .NET, so it depends on your use. The most general is - System.Threading.Timer

For more robust and full solution I would use a timing framework, for example Quartz.NET http://www.quartz-scheduler.net/

It all depends on your specific needs.

Maxim
  • 7,268
  • 1
  • 32
  • 44