I have a C# program that needs to dispatch a thread every X minutes, but only if the previously dispatched thread (from X minutes) ago is not currently still running.
A plain old Timer alone will not work (because it dispatches an event every X minutes regardless or whether or not the previously dispatched process has finished yet).
The process that's going to get dispatched varies wildly in the time it takes to perform it's task - sometimes it might take a second, sometimes it might take several hours. I don't want to start the process again if it's still processing from the last time it was started.
Can anyone provide some working C# sample code?
Use a while(True) loop in the thread. Record the start time at the top of the loop, perform the task, get the time again, calculate how much time has elaspsed and compare withv the start time. If this is less than X, convert the difference into ms and Sleep() for it.
No timer, no continual thread create, no synchro, no polling, no chance at all that two task instances will ever run concurrently.
you can just check if the thread is alive before you activate another thread.
do this using Thread.IsAlive.
I think a timer could work in this scenario. When the timer elapses it tries to obtain a lock on a synchronisation object. If it succeeds then it proceeds with it's work. If it fails to obtain the lock it knows the last thread has not finished so returns.
If you are using .Net 4.0 or above you could use Monitor.TryEnter(object, bool).
bool acquiredLock = false;
try
{
Monitor.TryEnter(lockObject, ref acquiredLock);
if (acquiredLock)
{
//do your work here
}
}
finally
{
if (acquiredLock)
{
Monitor.Exit(lockObject);
}
}
Related
I want to start a background thread on some user event, in which I wait/sleep 10 seconds to do something if a variable changes between the time it was passed in and the time it is checked. However, during that 10 seconds, the same user event can repeat, and I want to interrupt & reset the thread to use the new variable and start back at 10 seconds.
For example,
private static int index = 0;
private static Thread myThread = null;
if(myThread != null && myThread.IsAlive) {
// need to 'restart' the thread with updated index
/* Suspend? Resume? */
} else {
// create a new thread and start countdown
myThread = new Thread(new ThreadStart( some_Thread(index) ));
myThread.Start();
}
I read that suspend() and resume() are antiquated, and I've read up some posts on Auto/ManualResetEvent, but they're not exactly what I'm looking for. It's probably something closer to Abort() then Start() a new one, but apparently that's unwise.
So any suggestions how to achieve this with one static thread handle? Again, the 10 seconds 'sleep' has to be interruptible and, thereafter, the thread be discardable or restartable. Thanks!
I want to start a background thread on some user event,
You are doing what we at SO call an "XY problem". You have a completely wrong idea about how to solve a problem and you are asking questions about how to make that wrong way work. Instead, concentrate on the user focussed problem you really have and ask about that.
in which I wait/sleep 10 seconds to do something if a variable changes between the time it was passed in and the time it is checked.
Don't do any of this stuff. If you're making a thread whose job it is to sleep, odds are good that you are doing something very, very wrong. Threads are expensive; only make a thread if you're going to be scheduling a CPU to service that thread.
When you are considering making a thread, ask yourself "would I hire a worker to do this task?" Ten seconds of computer time is ten billion nanoseconds; that's like hiring a worker and paying them to sleep for centuries. You'd never do that; you'd just put "do this later" on your to-do list, and come back to it later. If it gets cancelled, you'd take it off your to-do list.
What you want to do instead is make zero extra threads. Make a cancellable asynchronous workflow that awaits a Task.Delay before it does the work that must be done ten seconds later. If the user event happens during the delay then cancel the workflow and start a new workflow.
If the work that follows the delay is CPU intensive, then schedule a worker thread and await the result. If it is not -- if it is CPU work that comes back in say 30 ms or less -- then just run the work on the main thread. If it is IO gated, then use the asynchronous version of the IO API to stay on the main thread. You want to be making as few threads as you can get away with here.
Be careful. Even though everything is still on one thread, there are still race conditions that are possible in cancellable workflows like this. You still need to consider all possible interleavings of the non-dependent parts of your asynchronous workflows.
I have a situation where I have multiple threads being executed at once. In some cases these threads will be put in a while() loop for an unknown amount of time, and if a certain number of threads get caught in this loop then eventually the scheduler stops letting other threads be executed.
I was wondering if there is some way I could delay a thread from being executed (remove it from the scheduled list) and then let other threads in. Is it then possible to wake up that thread later by a threadID or something like that?
I am reading about Task.Delay and see it suspends execution from a timespan and that it is possible to time something out for an infinite amount of time, but is it possible to time it out indefinitely UNTIL a event occurs and then undelay it by some name or ID?
Edit: I thought this question was one that was harder to post code for, but more or less I have a situation where requests come in and are put into a loop like:
while(true){
//check for something that could make me want to delete this thread/request
//do some things
}
I had noticed that when I sent large number of requests that I never stopped ended up still in his loop (which I understand), but it seems the max amount of threads that could be doing this is 16/32 (depends on my computer that I run it on) and it is stopping other requests from being scheduled to run.
I wanted to know if inside the while() loop I could do something like this:
while(true){
//put this thread to sleep
//do some things that
//call some function to wake up the specific thread I need to do work on, before I put it back to sleep
}
The difference in this now is that instead of 16/32 threads running I can have 1 "king thread" that enters this while() loop that can 'do some things' and then wake up the thread that needs to be affected by the 'things'. Is there a way to sleep and wake up a specific thread so that other threads can be scheduled to run?
From the question I guess that you are running a busy waiting loop. That's pretty bad as you found out.
Make the loop wait for an event:
while (true) {
WaitForEvent();
DoWork();
}
This requires cooperation from the thread (or component) that makes the event happen. You could use a ManualResetEvent or a TaskCompletionSource to make this coordination happen.
I can't really be more specific because the question is not particularly concrete about the scenario. I hope this pushes you in the right direction.
I am writing a "game" simulating Student's Adventures at The University and what I have done already is few forms, still I need one form to not wait for user input but check if I want an Game Event to run now, if not, then wait few seconds and then skip to another day and repeat the procedure for that day.
The thing is user is able to quit the game at any time and all the information is saved so I need to keep it an one-shot timer of few seconds that doesn't run for another time after it expires.
How do I write an one-shot timer or delay an execution of my c# code for few seconds?
EDIT:
MessageBox.Show("I will wait 3 seconds now");
wait 3 seconds
...
after 3 seconds
MessageBox.Show("3 seconds passed since I poped out last message box!");
If all that you want to do is create a method to "tick" every so often, there are a few options.
The first would be the System.Threading.Timer object, documented on MSDN here: http://msdn.microsoft.com/en-us/library/system.threading.timer%28v=vs.110%29.aspx
An example of this:
public void Tick(object stateInfo /* required to fit TimerCallback signature */)
{
/// add your code here
}
And your Timer instantiation would look like so:
System.Threading.Timer timer = new System.Threading.Timer(Tick, null, 0, 3000);
And thereafter Tick() will be executed every 3 seconds. Feel free to replace the null with an object of your choice so as to keep track of state.
A second, worse choice would be to use a BackgroundWorker. The primary advantage I've found in this is that the ProgressChanged event handler is automatically invoked in the primary UI thread, so you can use it fairly easily for cross-thread code that involves the UI in some sense. Here's the documentation on MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=vs.110%29.aspx
I don't think the BackgroundWorker would be a good choice - it's user-friendly, but it's not really designed to persist infinitely, or activate periodically, so its usage leads to bad workarounds like wrapping all the DoWork code in a while(true) loop and using Thread.Sleep() to pause execution.
A third would be the System.Timers.Timer object, which takes an Interval in milliseconds and an Elapsed event hooked into one of your methods. Each time the interval passes, your method is called. The documentation for that is here: http://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx
Note that all of these work slightly differently, so one may well fit your use case significantly better. We can't really tell you which one is best because we don't really know much about your implementation right now.
http://msdn.microsoft.com/library/system.threading.timer.aspx
static void Main(string[] args)
{
Timer tmr = new Timer(S, null, 0, 5000);
Console.Read();
}
static void S(object obj)
{
Console.WriteLine("1");
}
and u can look here
Execute a method after delay on time only
This is a rather simple issue, but every time I try to find the answer it keeps showing things about Windows Scheduled Tasks, and this is not what this is.
Say my program is basically this:
void StartDoingThings()
{
//At Specific System.DateTime
DoSomething()
//At another specific System.Datetime
DoSomethingElse()
}
What do I put instead of those comments to cause those methods to run at separate datetimes.
I could use Thread.Sleep() or even System.Threading.Timers and calculate intervals based off of (DateTimeOfEvent - DateTime.Now), but is there simply something to say (assuming the program is still running): At 9:30:00 AM on 11/30/2012, perform the method DoAnotherThing() ?
If you want to "schedule" a method to do something at a predetermined time, there are a number of ways to do that. I would not use Thread.Sleep() because that would tie up a thread doing nothing, which is a waste of resources.
A common practice is to use a polling method that wakes up on a regularly timed schedule (let's say once a minute) and review a shared list of tasks to perform. System.Timer can be used for the polling method:
aTimer = new System.Timers.Timer(10000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
The OnTimedEvent method can contain code that maintains a collection of "tasks" to perform. When a task's time comes up, the next run of the Timer will cause it to execute.
here i have written a window service, it job is to read files from one folder and sending the same content to database and sending readed files to some other folder
now my service having timer event has sets it was about of 10000 means ten seconds,
now if a process a files between 100 - 1000 ,with in 10 sec it was doing that job processing good output, case if process the files 6000 - 9000 at that particular situation my service is not producing exact out, it was not able to do that job in 10000 (ten seconds), so i need when service in middle of the job it should get interrupted since by timer completed but real scenario it should completed the particular job.
kindly give some suggestions, it would be appreciated
Different approaches that can work:
Have the method called by the timer safe for re-entrance and then not worry about it. This tends to be either very easy to do (the task done is inherently re-entrant) or pretty tricky (if it's not naturally re-entrant you have to consider the effects of multiple threads upon every single thing hit during the task).
Have a lock in the operation, so different threads from different timer events just wait on each other. Note that you must know that there will not be several tasks in a row that take longer than the time interval, as otherwise you will have an ever-growing queue of threads waiting for their chance to run, and the amount of resources consumed just by waiting to do something will grown with it.
Have the timer not set to have a recurring interval, but rather re-set it at the end of each task, so the next task will happen X seconds after the current one finishes.
Have a lock and obtain it only if you don't have to block. If you would have to block then a current task is still running, and we just let this time slot go by to stay out of it's ways.
After all, there'll be another timer event along in 10 seconds:
private static void TimerHandler(object state)
{
if(!Monitor.TryEnter(LockObject))
return;//last timer still running
try
{
//do useful stuff here.
}
finally
{
Monitor.Exit(LockObject);
}
}
Use a static boolean variable named something like IsProcessing.
When you start working on the file you set it to true.
When the timer is fired next check if the file is still in processing.
If it's still processing, do nothing.