I'm new in C# and I'm using System.Threading.
I have this code:
UISystem.SetScene(Scene_Menu);
Thread.Sleep (9000);
p.Text="HELLO";
Thread.Sleep(9000);
p.Text="WORLD";
It delays 18 seconds, but the p.Text="HELLO" doesn't show between the sleep functions. What's the problem with my code?
Thanks.
Timers don't work since I can't edit p from a separate thread.
Application.DoEvents() is a Windows Forms function, I'm building an application in PS Vita.
You have discovered why you should never use Thread.Sleep. It is useful for only two things. (1) Writing test cases that need to simulate a thread being busy for a certain number of seconds, and (2) Sleeping for zero milliseconds tells the operating system "I cede the rest of my time slice to another process if there exists one that wants it"; it's a politeness thing.
You should never use thread.Sleep to introduce a delay as you are doing for exactly the reason you have discovered. You are setting a property, but setting a property does not cause the operating system to repaint the screen. Consider if it did; you might have a thousand property sets in a method, and you would have to repaint the screen after all of them, which would look ugly and be very slow.
Instead what happens is the property is set and the object makes a note to the operating system that says when this thread is available to handle operating system messages again, please repaint me. Your program is, instead of telling the operating system "I'm done, go ahead and see if there are any message for me" that instead you want the thread to do nothing for nine seconds.
Now, you can tell the program to check for messages by calling DoEvents but using DoEvents is also a bad idea and you should not do it. Doing so essentially causes your program to exhibit symptoms of Attention Deficit Disorder; you have not finished the current job and you are looking to see if there are new jobs to do without removing the old jobs from the call stack! Suppose those new jobs in turn get interrupted, and so on, and so on. The stack grows without bound, which is very bad. DoEvents is a "worst practice", just like sleeping a thread. You can get away with it in small simple programs but it leads to big trouble when the program becomes complex.
Moreover: yes, DoEvents will paint your control, but that is all it will do. For the next nine seconds, the application will appear to the user to be completely hung. That is a very bad user experience.
The right thing to do if you want to introduce a delay is to asynchronously wait. In C# 4 and earlier the standard way to do that is to create a timer, and when the timer ticks, do the next thing.
Now, you say that you cannot use a timer because you need to access the control from the UI thread. That's fine. The timer's tick event handler will run on the UI thread, not on a separate thread. You can safely use a timer.
In C# 5, the right thing to do is to use the new await keyword to introduce an asynchronous wait. That is, a wait that does other stuff while it is waiting, instead of going to sleep while it is waiting. In C# 5 you would write your code as:
UISystem.SetScene(Scene_Menu);
await Task.Delay (9000);
p.Text="HELLO";
await Task.Delay(9000);
p.Text="WORLD";
C# 5 is at present in beta; for details on this new feature see:
http://msdn.microsoft.com/en-us/async
For a gentle introduction to async and an explanation of why DoEvents is bad news, see my MSDN magazine article:
http://msdn.microsoft.com/en-us/magazine/hh456401.aspx
Related
Help with ideas for redesign of the below C# program would be greatly appreciated. I am trying to pick between implementing multithreading using 1) TAP, 2) course-grained threads that contain spinners that terminate when their bools are set to false, or 3) the same threads using signalling instead of these bools. I will explain the program below, to make the case clear.
The Program
The program is a game automation application in C# that I am developing as a fun way to learn the language and C# (5.0) features better. It has a UI that needs to remain responsive while the app runs.
When a particular tab in the UI is opened, the program fires up a new thread called "Scan" that, in a new method in another class, scans various memory locations and updates labels in the UI with these quickly changing values using the UI's SynchronizationContext. This goes on in a while(scanning) loop, for as long as scanning bool is true (usually the full life-duration of the program).
When the user clicks the Start button on this tab, the program fires up two new threads that does the following: Thread "Run" moves the character around following a particular path. Thread "Action" hits particular buttons and performs actions at the same time as the player runs the path. If a certain scenario occurs, the program should stop the running thread and the action thread temporarily, run a method, and when it finishes, go back to the running and action'ing.
When the user clicks the Stop button on this tab, the automation should halt and threads terminate.
The Challenge
I have already created a working version using continuous spinner loops in each thread that takes care of the various work. The spinners run using a while(myBool). For the three threads the bools are: scanning, running and actioning.
When I want to stop a thread I set the bool to false, and use a Thread.Join to wait for the thread to terminate gracefully before proceeding. The threads can, as mentioned, be stopped by the user clicking the Stop button, or automatically by the program as part of its functionality. In the latter case a thread is stopped, Joined, and then at a later stage restarted.
After having done a lot of reading and research on threading and the new async programming tools in C# 5.0, I have realized that the way I am currently doing it might be very clumsy and unprofessional. It creates lots of synchronization/thread-safety issues, and as the goal of all of this is to learn more about C# I wanted to get your take on whether I should change it to a fine-grained asynchrounous programming approach instead, using TAP with async and await as appropriate.
Does this sound like a case where Tasks with cancellation tokens could be useful? The threads are after all long-running operations, so I was concerned that using the thread pool (Task.Run) would cause bad hygiene in the thread pool (over-subscription). If async programming seems like a bad match here, what about using threads as I have done, but instead use signalling to start and stop the threads?
Any thoughts greatly appreciated.
No. TPL was designed to run shorter tasks where the allocation of new threads all time would hurt perfomance. It got quite nice features like job queues and work stealing (a TPL thread can take jobs from another thread). It can of course have longer running task, but you wont get so many benefits from that. On the contrarary, you force TPL to allocate new threads.
However, the question is a bit general in the sense that we need more information about your actual implementation to know what you should use. For the Scan thread it's quite obvious that it should run in a single thread.
But for the others it's hard to know. Do they do work all the time or periodically? If they do work all the time you should keep them in seperate threads.
As for the thread syncronization there is another alternative. You could use a ConcurrentQueue to queue up everything that has to be drawn. In that way you do not need any synchronization. Just let the UI thread check the queue and draw anything in it, while the producers can continue to do their work.
In fact, in that way you can move anything not related to UI drawing to other threads. That should also improve the responsiveness in your application.
public void ActionRunnerThreadFunc()
{
_drawQueue.Enqueue(new SpaceShipRenderer(x, y));
}
public void UIThreadFunc()
{
IItemRender item;
if (_drawQueue.TryDequeue(out item))
item.Draw(drawContext);
}
I have a task. I have some random number, wich contains value of this number, and delay.
Delay means, that after this delay (in seconds) this number gonna be updated (value and delay).
And all I need to do is next: for example I have 5 numbers. All of them are on the same form. So when programm start, it must take first number, get its delay, do smth like Thread.Sleep(delay) for this number, update it, then get second number, get delay and so on. When it reach the last one, it must get first number again, then second and so on. Like loop.
I'm new in threads. So could someone explain me how should it work?
So I have main form, then I have 5 UserControls on it (I keep them in List<>). Each control have UpdateNumber() method, which update value and delay of current number. What should I do on main form? Do I need create Thread[] array? Then put each UserControl in there? Then start all of them and monitor them somehow?
I think it smth about Thread.Join. But for me, as for newbie it's pretty complicated.
P.S. and than I need to next task. It's the same, but all this numbers works separetly. For example first numbers has 5 second delay in the begining. When it reachs 5 second delay, it's update itself. Second number and all others do the same.
I would avoid creating threads and using Thread.Sleep(). Each thread is an expensive resource to create and since it will be asleep the majority of the time, it will be wasted the majority of the time. Also, when it executes it may cause context switching since the CPU's may be saturated.
Instead, I would consider using a System.Threading.Timer. For instance, you initially set the Timer to operate on the first value. After this operation is complete you use your 'delay' to set the Timer to execute the code that will read the next value using Timer.Change() and so on. I'm not sure I understand your requirements completely but it sounds like you should be able to satisfy most of them using a Timer. The Timer will use the ThreadPool which will avoid unnecessary thread creation and context switching.
To learn more about multi-threading I highly recommend Jeffrey Richter's book CLR via C# (part V). Multi-threading is very powerful but it is incredibly easy to get totally wrong. IMHO anyone who wants to write multi-threaded code should at least read a good text such as this before starting.
Based only on what I have read I do not see any compelling reason to use threads at all. I mean you are just generating different random numbers based on some time interval so it cannot possibly be that CPU intensive. Just use a System.Windows.Forms.Timer in each UserControl. When the Tick event handler is executed then just generate next number.
If you are asking if it is a good idea to run each UserControl in a different thread then the answer is most definitely no. All UI elements including Form's and Control's must run in the specially designated UI thread. This is mandatory. It will not work right correctly (or at all) on a free thread.
Regarding calling Thread.Join; do not attempt this, at least on a UI thread anyway. Calling Join on a UI thread will block the windows message dispatching mechanisms. It will appear as if the whole UI hung up.
I'm doing all this in C#, in Visual Studio 2008.
I want to slow down the work of my algorithm so that the user can watch it's work. There is a periodic change visible at the GUI so I added Thread.Sleep after every instance.
Problem is that Thread.Sleep, when set to at least a second, after a few instances of Thread.Sleep (after few loops) simply freezes entire GUI and keeps it that way till program completion. Not right away, but it always happens. How soon depends on the length of the sleep.
I have proof that entire program does not freeze, it's working it's thing, even the sleep is making pauses of correct length. But the GUI freezes at certain point until the algorithm ends, at which point it shows the correct final state.
How to solve this issue? Alternative to pausing algorithm at certain point?
First off, don't make the user wait for work that is done before they even think about when it will be finished. Its pointless. Please, just say no.
Second, you're "sleeping" the UI thread. That's why the UI thread is "locking up." The UI thread cannot be blocked; if it is, the UI thread cannot update controls on your forms and respond to system messages. Responding to system messages is an important task of the UI thread; failing to do so makes your application appear locked up to the System. Not a good thing.
If you want to accomplish this (please don't) just create a Timer when you start doing work that, when it Ticks, indicates its time to stop pretending to do work.
Again, please don't do this.
I'd guess everything is running out of a single thread. The user probably invokes this algorithm by clicking on a button, or some such. This is handled by your main thread's message queue. Until this event handler returns, your app's GUI cannot update. It needs the message queue to be pumped on regular basis in order to stay responsive.
Sleeping is almost never a good idea, and definitely not a good idea in the GUI thread. I'm not going to recommend that you continue to use sleep and make your GUI responsive by calling Application.DoEvents.
Instead, you should run this algorithm in a background thread and when it completes it should signal so to the main thread.
You are about to commit some fairly common user interface bloopers:
Don't spam the user with minutiae, she's only interested in the result
Don't force the user to work as fast as you demand
Don't forbid the user to interact with your program when you are busy.
Instead:
Display results in a gadget like a ListBox to allow the user to review results at her pace
Keep a user interface interactive by using threads
Slow down time for your own benefit with a debugger
This depends on a lot of things, so its hard to give a concrete answer from what you've said. Still, here are some matters that might be relevant:
Are you doing this on a UI thread (e.g. the thread the form-button or UI event that triggered the work started on)? If so, it may be better to create a new thread to perform the work.
Why do you sleep at all? If the state related to the ongoing work is available to all relevant threads, can the observer not just observe this without the working thread sleeping? Perhaps the working thread could write an indicator of the current progress to a volatile or locked variable (it must be locked if it's larger than pointer size - e.g. int or an object - but not otherwise. If not locked, then being volatile will prevent cache inconsistency between CPUs, though this may not be a big deal). In this case you could have a forms timer (there are different timers in .Net with different purposes) check the status of that variable and update the UI to reflect the work being done, without the working thread needing to do anything. At most it may be beneficial to Yield() in the working thread on occasion, but its not likely that even this will be needed.
Could you please tell me how do I go about pausing my program for 500 milliseconds and then continue?
I read Thread.Sleep(500) is not good as it holds up the GUI thread.
Using a timer it fires a callback ...
I just want to wait 500ms and then continue to the next statement.
Please advise.
EDIT: I need to display a status bar message for 500ms and then update the message with a different one. Sorry, I meant 500 not 50.
EDIT: I do understand what all you have said. but: [I just want to wait 500ms and then continue to the next statement.] I think because it is such a short interval i am going do a Thread.Sleep(500) on the main GUI thread. Otherwise i would have to rewrite a lot of code to accomodate this brief interval of 500 milliseconds.
EDIT: i will try to reformat my status message so the pause is not needed.
Hmya, what you're trying to do is pretty fundamentally incompatible with the Windows programming model. A native Windows program is event driven. Your program is always idle, sitting inside a loop started by Application.Run(), waiting for Windows to tell it that something interesting happened that it should respond to. Paint requests, mouse clicks, timer expirations, stuff like that.
Your program should respond to this and filter what is interesting to you. When you drop a button on a form, you are always interested in the Click event, generated when Windows sends the MouseDown notification message. Your Click event handler runs some kind of custom code that you write. Like updating a status bar message in your case.
Updating the status bar message half a second later doesn't make a whole heckofalot of sense. What exactly happened during those 500 milliseconds that changed the way your program responds to events? You can call the Update() method of the StatusBar so the new message is visible, then call System.Threading.Thread.Sleep(500) to get what you want. You'll get away with it, the "Not Responding" ghost that Windows puts up takes your program going dead for several seconds.
But that doesn't make a lot of sense, nothing happened during that half second, the state of your program didn't change. It couldn't change, it was dead to Windows and not receiving any messages that would allow it to change state.
Well, that's about as far as I can take this. Please update your question and explain why you need to do this. Just in case: if you're contemplating this to fake doing something important for half a second, your user will not be impressed. She'll eventually notice your UI is dead for half a second without anything to show for it.
You have two choices:
Use a timer as you suggested. Split your method up into two methods, foo1 and foo2. Use the foo1 to start the timer and run foo2 in the callback.
Use a BackgroundWorker for running the entire function and use Thread.Sleep on the worker thread.
From your update it seems that the only thing you want to do is change a single field. I would definitely recommend the first method: using a timer. Starting a BackgroundWorker for this task is overkill and will just give you unnecessary extra work and complications.
Instead of pausing the UI directly for 500 ms, you can always use a BackgroundWorker. That will cause your callback to run in a separate thread, where you can use Thread.Sleep to pause it without blocking the UI. Then when you are done, just update the status bar with your new message.
More context to the question would be helpful.
Thread.Sleep(50) will pause the current thread for 50 milliseconds. If you're doing this in the UI thread, then yes, it will freeze the UI for 50 milliseconds. However, if you use a different thread to do this processing, then calling Sleep on that thread will pause it for 50 milliseconds without freezing your UI thread.
See Marc's answer to this question for an example on using a BackgroundWorker instance to do what you need.
In C# your best bet is to use the Timer and fire a callback.
In F# there is an awesome way to do what you want, see
F# async on the client side
which shows how to write straight-line code and have the language take care of the callbacks for you.
You need to allocate another thread. In that thread you Sleep(500) and change the needed data. Caution: you would need to use the original thread's dispatcher, because the data related to UI should be usually updated from the GUI thread.
I have a problem with interface lag in C#.
Since I'm still learning please be patient whilst I explain.
I have narrowed the problem to my timer object.
Basically my program queries a device through TCP/IP socket and outputs it to a textbox on screen.
Now I am polling the device for data every second which requires some logic to be buried within timer object and the following is what happens between ticks:
Increment a value.
Construct the 2 strings that represents the command to be sent to
the box (encapsulated in a function
Encode the command
Send command
Clear the byte array
Receive reply.
Could this be too much processing being done in the event handler? Every time I try to move the window during the polling session i.e. when the timer is running I get a very bad input lag.
The timer you are using is executing on the windows message thread. Therefore, while the polling is running the windows message queue is blocked. This isn't a problem with doing too much processing, most of the time the thread will be waiting for the TCP/IP response.
To fix this, you just have to do the do the work on a background thread and then update the UI on the UI thread.
There are a heap of different timers in the .NET framework that work in different ways, the one you are using works processed the timer event on the same thread, others work on background threads. Check this article out about the different timers.
You could also just use your current timer to invoke a BackgroundWorker component to do the work on the background thread. The main benefit of this is the the BackgroundWorker will do the work on a background thread, but will raise the work complete event on the UI thread so that it is simple to update the UI without having to worry about which thread you are on.
I think this is because you're trying to do work in your UI thread. Have your timer run in a background work thread.
It seems like there are a few things going on. First, you may be doing too much in your timer tick handler. How are you constructing the string and encoding the command? Can any of this be done once outside the tick handler or simplified in any way (using String.Format calls, for instance)? There are actually three different timers available in .NET, with different resolutions. Which timer are you using?
The biggest issue is the fact that your interval is 1 second. No matter what, that is a lot of processing overhead. Keep in mind that, for the most part, every time the interval is hit and the tick handler is invoked you are causing a context switch between threads. There is a bit of overhead involved in this (nothing which you can do anything about) and the more often you context switch the slower your performance appears.