I have this code doing what I want:
TriggerSomeExternalProcess();
double secondsElapsed = 0;
DateTime startTime = DateTime.UtcNow;
double timeoutInSeconds = 10;
while (secondsElapsed < timeoutInSeconds) {
// TODO: this seems bad...
secondsElapsed = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
}
CheckStatusOfExternalProcess();
The goal is to TriggerSomeExternalProcess and then CheckStatusOfSomeExternalProcess - but that process runs on the same thread so I can't do Thread.Sleep(). It's an ongoing process that can't be awaited.
I feel like the above while loop is wrong - what pattern do you employ when you need to wait without blocking your thread?
copy-pasted from a comment on one of the answers
unfortunately I can't touch the code in the ExternalProcess. I'm writing a test and those are the methods I have access to. I know it's less than ideal
Instead of using a CheckStatusOfExternalProcess() Method u may be able to add an StatusChangedEvent onto the ExternalProcess thing and attach a EventHandler onto it. That way your eventhandler gets called, when the status has changed.
Is that a possibility for you?
Btw: If both of your processes run on the same Thread - how can that be not blocking?
I assume the process that's external is not your own.
Therefore it can't take a callback action.
It can't give a heartbeat (send periodically back it's current status).
And it can't subscribe to it's status changing.
These would be the normal ways to deal with it.
In which case you could just use something like this
Task.delay(TimeSpan.FromSeconds(10))).ContinueWith(() => CheckStatusOfExternalProcess())
continue with will fire as soon the first task is complete but now you can continue on in your code without worrying about it
Related
I'm writing an application working with a big and ugly 3rd party system via a complicated API.
Sometimes some errors happen in the system, but if we wait for my program to face this errors it can be too late.
So, I use a separate thread to check the system state as following:
while (true)
{
ask_state();
check_state();
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
}
It doesn't really matter if I check the system state once in 100 ms or once a minute.
But I have heard that using Thread.Sleep() is a bad practice. Why? And what can I do in this situation?
One reason is that Thread.Sleep() is blocking your code from doing anything else. Recent efforts is to make blocking as least as possible. For example, node.js is a non-blocking language.
Update: I don't know about the infrastructure of Timer class in C#. Maybe it's also blocking.
You can schedule a task to check that third API every 100 ms. This way, during that 100 ms, your program can do other tasks.
Update: This analogy might help. If we compare operating system to a hospital, and compare the threads to nurses in that hospital, the supervisor (programmer) can choose a policy:
Either to ask each nurse (thread) to watch one, and only one patient (a job, a task to be done), even if between each check she waits for an hour (Sleep() method)
To ask each nurse to check each patient, and during the interval till next check, go on and check other patients.
The first model is blocking. It's not scalable. But in the second model, even with few nurses, you might be able to serve many patients.
Because the only way to shut down this thread if it's waiting inside the Sleep is to either a) wait for the Sleep to end, or b) use one of Thread.Abort or Thread.Interrupt.1
If it's a long sleep, then (a) isn't really suitable if you're trying to be responsive. And (b) are pretty obnoxious if the code happens to not actually be inside the Sleep at the time.
It's far better, if you want to be able to interrupt the sleeping behaviour in a suitable fashion, to use a waitable object (such as e.g. a ManualResetEvent) - you might then even be able to place the wait on the waitable object into the while conditional, to make it clear what will cause the thread to exit.
1 I've use shutdown in this instance because it's a very common scenario where cross-thread communication is required. But for any other cross-thread signalling or communication, the same arguments can also apply, and if it's not shutdown then Thread.Abort or Thread.Interrupt are even less suitable.
i would set a timer to whatever ms you want and wait for my check methods to complete, by the way do you want to use an eternal loop or it is not a complete code that you showed up there ?
ok this is a sample of what i'm talking about:
public void myFunction()
{
int startCount = Environment.TickCount;
ask_state();
check_state();
while (true)
{
if (Environment.TickCount - startCount >= 20000) //two seconds
{
break;
}
Application.DoEvents();
}
}
//Now you have an organized function that makes the task you want just call it every
// time interval, again you can use a timer to do that for you
private void timer_Tick(object sender, EventArgs e)
{
myFunction();
}
good luck
I'll be short and to the point. I basically need a way I can take a timer, check when the timer is up and execute something at the end of it, then loop it. For example (this code isn't serious, just example code) :
Timer1.start();
If (timer1.TimeRanOut) {
Timer2.start()
}
Or some other way to pause the timer without the GUI freezing up (I'll be running some things at a fast pace and freezing would get in the way). I'll be making this more complex by looping the entire process, like :
if (Checkbox1.checked == true; )
{
Timer1.start();
Next If (timer1.TimeRanOut) {
Timer2.start()
}
Next If (timer2.TimeRanOut) {
Timer3.start()
}
And so on. Any solutions?
I would suggset working with Tasks. you set up a task to do something (it can just wait for X seconds, than it is a timer) than you set continueWith to assign a new task to run when the first one is finshed.
You can read more about this here:
http://msdn.microsoft.com/en-us/library/dd537612.aspx
And by the way, you really should not run heavy calculations on the UI thread itself.
If you decide to use tasks - that would be fine. Otherwise , you need to create background thread and do the work there.
Edit:
After some clarification from the OP , I will try to explain the basics or working with UI and background threads:
When you run a winforms/WPF application, all of the user interface events are handled in a single thread - the UI thread. it goes over all of the events and processes them.
If long calculation occupy this thread, the UI will become "stuck" and o responsive. see:
UI freezes on heavy calculation
That is why, any long calculations should be done on another thread, in the background.
In the above post's answer there is an example on how to do this.
You could use the System.Threading.Timer. You would then make use of its single shot capability (see Change method). Such you may chain several timers.
The callback of this timer runs on the thread pool so your UI doesn't freeze.
So I have been playing around with threads for the last couple months and while my output is as expected i have a feeling I'm not doing this the best way. I can't seem to get a straight answer from anyone i work with on what is best practice so i thought i would ask you guys.
Question: I'm going to try to make this simple so bear with me. Say i have a form that has a start and stop button. The start button fires and event that starts a thread. Inside this thread's DoWork it is going to call 3 methods. Method1() prints to the console "A\n" 10 times with a pause of 10 seconds in between. Method2() and Method3() are the exact same just different letter and different pause times in between Console.WriteLine. Now when you press the stop button you want the response to be immediate. I don't want to have to wait for the methods to complete. How do i go about this?
The way i have been doing this is passing my BackgroundWorker to each method and checking the worker.CancellationPending like so
public void Method1(BackgroundWorker worker)
{
for(int i = 0; i < 10 && !worker.CancellationPending; ++i)
{
Console.WriteLine("A");
for(int j = 0; j < 100 && !worker.CancellationPending; ++i)
{
Thread.Sleep(100);
}
}
}
Like i said this give me the desired result however imagine that method1 becomes a lot more complex, let say it is using a DLL to write that has a keydown and a key up. If i just abort the thread i could possibly leave myself in an undesired state as well. I find myself littering my code with !worker.CancellationPending. Practically every code block i am checking CancellationPending. I look at a lot of example on line and i rarely see people passing a thread around like i am. What is best practices on this?
Consider using iterators (yield return) to break up the steps.
public void Method1(Backgroundworker worker)
{
foreach (var discard in Method1Steps)
{
if (worker.CancelationPending)
return;
}
}
private IEnumerable<object> Method1Steps()
{
for (int i = 0; i < 10; ++i)
{
yield return null;
Console.WriteLine("A");
for (int j = 0; j < 100; ++i)
{
Thread.Sleep(100);
yield return null;
}
}
}
This solution may be harder to implement if you have a bunch of try/catch/finally or a bunch of method calls that also need to know about cancelation.
Yes, you are doing it correctly. It may seem awkward at first, but it really is the best option. It is definitely far better than aborting a thread. Loop iterations, as you have discovered, are ideal candidates for checking CancelationPending. This is because a loop iteration often isolates a logical unit of work and thus easily delineate a safe point. Safe points are markers in the execution of a thread where termination can be easily accomplished without corrupting any data.
The trick is to poll CancelationPending at safe points frequently enough to provide timely feedback to the caller that cancelation completed successfully, but not too frequently to negatively effect performance or as to "litter the code".
In your specific case the inner loop is the best place to poll CancelationPending. I would omit the check on the outer loop. The reason is because the inner loop is where most of the time is spent. The check on the outer loop would be pointless because the outer loop does very little actual work except to get the inner loop going.
Now, on the GUI side you might want to grey out the stop button to let the user know that the cancelation request was accepted. You could display a message like "cancelation pending" or the like to make it clear. Once you get the feedback that cancelation is complete then you could remove the message.
Well, if you are in the situation where you have to abort a CPU-intensive thread, then you are somwhat stuck with testing an 'Abort' boolean, (or cancellation token), in one loop or another, (maybee not the innermost one - depends on how long this takes). AFAIK, you can just 'return' from the inner loop, so exiting the method - no need to check at every level! To minimize the overhead on this, try to make it a local-ish boolean, ie try not to dereference it through half-a-dozen ...... classes every time .
Maybee inherit classes from 'Stoppable', that has an 'Abort' method and a 'Stop' boolean? You example thread above is spending most time sleeping, so you get 50ms average latency before you get to check anything. In such a case, you could wait on some event with a timeout instead of sleeping. Override 'Abort' to set the event as well as calling the inherited Abort & so terminate the wait early. You could also set the event in the cancellationToken delegate/callback, should you implement this new functionality as described by Dan.
There are acually very few Windows API etc. that are not easily 'unstickable' or don't have asynchronous, 'Ex' versions, so it's err.. 'nearly' always possible to cancel, one way or another, eg. closing sockets to force a socket read to except, writing temporary file to force Folder Change Notifications to return.
Rgds,
Martin
How do you implement busy waiting in a not total inefficient way? I am facing the issue that I can load the data of my model only in a pull manner, which means I have to invoke getXYZ() methods in a continuous way.
This has to happen not fast enough for user interaction, but fast enought, that when a state in the GUI is changed, the model can be noticed and the new state is received by the getXYZ() methods.
My approach simply be:
while (c.hasChanged()) {
Thread.sleep(500);
}
updateData();
Are there better mechanisms?
Your problem seems to be solvable with Threading.
In WPF you can do:
Thread t = new Thread((ThreadStart)delegate() {
while (true) {
Thread.sleep(500);
if (c.hasChanged())
Dispatcher.Invoke((Action)delegate() {updateData();});
}
}).Start();
In WinForms
Thread t = new Thread((ThreadStart)delegate() {
while (true) {
Thread.sleep(500);
// this must derive from Control
if (c.hasChanged())
this.Invoke((Action)delegate() {updateData();});
}
}).Start();
There may be missing parameters to Invoke (which is needed to execute the code on the calling UI thread) but I'm writing this from my brain so no intellisense at disposal :D
In .NET 4 you can use TaskFactory.StartNew instead of spawning a thread by yourself.
In .Net <= 4, you could use the TreadPool for the thread.
However I recall you need this to be run at once because you expect it to be there checking as soon as possible and the thread pool won't assure you that (it could be already full, but not very likely:-).
Just don't do silly things like spawning more of them in a loop!
And inside the thread you should put a check like
while (!Closing)
so that the thread can finish when you need it without having to resort to bad things like t.Abort();
An when exiting put the Closing to true and do a t.Join() to close the checker thread.
EDIT:
I forgot to say that the Closing should be a bool property or a VOLATILE boolean, not a simple boolean, because you won't be ensured that the thread could ever finish (well it would in case you are closing the application, but it is good practice to make them finish by your will). the volatile keyword is intended to prevent the (pseudo)compiler from applying any optimizations on the code that assume values of variables cannot change
It's not clear from your post exactly what you are trying to do, but it sounds like you should put your model/service calls on a separate thread (via Background worker or async delegate) and use a callback from the model/service call to notify the UI when it's done. Your UI thread can then do busy things, like show a progress bar, but not become unresponsive.
If you are polling from a GUI, use a (WinForms) Timer.
If this is some kind of background process, your Sleep() may be the lesser evil.
Explicit busy waiting is evil and must be avoided whenever possible.
If you cannot avoid it, then build your application using the Observer design pattern and register the interested objects to an object which performs the polling, backed by a thread.
That way you have a clean design, confining the ugly stuff in just one place.
I want to wait for 15 seconds, then the control should resume from the next statement.
I don't have anything else to do while waiting (Just waiting).
I know that there is Thread.Sleep(15000). What I don't know is the best method to wait? What are the limitations of this?
The code would be like this:
Method()
{
statement 1;
statement 2;
//WaitFor 15 secs here;
statement 3;
}
The disadvantage of Thread.Sleep is if this is called in your GUI thread (the thread that processes GUI events, for example, a button click handler method, or a method called from a button click handler, etc.) then you application will appear to freeze and be nonresponsive for those 15 seconds.
It would be perfectly fine if you had explicetly created a seperate thread and called Thread.Sleep in it, assuming you don't mind that thread not doing anything for 15 seconds.
The alternative would be to create a Timer and start it after stmt 2, and place stmt 3 in the Tick event handler for the timer, and also stop the timer in that handler.
This may not be a direct answer to your question. I would say check whether your process flow is better than checking whether the code is better ;-)
Are you waiting for 15 seconds just to make sure stmt2; is complete? If so then adding an handler, as soon as stmnt 2 is executed, would be a better solution (?)
You can also use a timer to wait. Thread.sleep is a bad design. We have a similar question which talks about the comparison using Thread.sleep and Timer.
Try something like the following:
void Method()
{
console.log('statement 1');
console.log('statement 2');
var timer = new System.Threading.Timer(
o => // timer callback
{
console.log('statement 2');
},
15000, // Delay
0 // Repeat-interval; 0 for no repeat
);
}
Syntax is C# 3.0, uses a lambda expression to effectively create a closure around statement #3. With this, you could use any local variables of Method. A thing to note, however, is that with this method, or any other timer-based method...the function will return immediately after creating the timer. The function won't block until the Timer executes. To achieve that, the only thing I can think of is to actually use threads and make Method() block on a signal (i.e. WaitHandle, ResetEvent, etc.) until the timed call on the other thread completes.
Thread.sleep seems a sensible thing to do if there isn't anything else to do while waiting.
It puts the thread to sleep for that time so it doesn't use any CPU resources.
You could always use a timer and then execute code after the set duration. However, if you don't actually have to do anything and just want to wait at a particular point in code, then I think Thread.Sleep(150000); is sufficient.
[Edit: spelling]
If you always want to wait for a given time, then Sleep is useful. Obviously you shouldn't do this on a thread where timely responses are expected.
Keep in mind that your thread will sleep for the duration in all cases. If for some reason you want the thread to resume sooner, you're better off using signaling or callbacks. By using either of these instead of Sleep, you will minimize the needless wait time.
void Method()
{
Statement1();
Statement2();
// Start the timer for a single 15 second shot.
// Keep a reference to it (Mytimer) so that the timer doesn't get collected as garbage
Mytimer = new System.Threading.Timer((a) =>
{
// Invoke the 3rd statement on the GUI thread
BeginInvoke(new Action(()=>{ Statement3(); }));
},
null,
15000, // 15 seconds
System.Threading.Timeout.Infinite); // No repeat
}
I don't sure 100%, but if you really need your method to return after waiting 15 sec, try following:
Method()
{
stmt1();
stmt2();
int time = DateTime.Now.Millisecond;
while (15*1000 > DateTime.Now.Millisecond - time)
{
Thread.Sleep(10)
Application.DoEvents();
}
stmt3();
}