How to add actual wait? - c#

Im currently trying to code very simple thing.
what it supposed to do:
enter google
wait 5 seconds
search something.
now, the part I cant do is wait.
There is thread sleep etc. but they stop GUI and makes my program unusable.
I can also do it with timers but it isnt very effective way to do it, since in actual app there will be many waits...
Are there anyway to do with it like 2-3 lines of code only, and without stopping GUI?

A timer is exactly what you want here - you want to say, "In 5 seconds, do X" (potentially executing in the UI thread) which is exactly what a timer does for you. If you want to encapsulate that in a single method which you can pass in an Action and a TimeSpan or whatever, that's fine - but a timer is definitely the way to go.
(The type of timer you want to use will depend on what thread you want the timer to fire on, etc.)

You need to do the work on a seprate thread so it dosent halt the GUI thread.
Thread worker = new Thread(dowork);
worker.Start();

Related

What happens while using System.Threading.Timer?

I am a newbie to dotnet, and I have a C# code in a Windows Service application which have to run for every 24hours. For specifying the interval I used the below code:
var t=new System.Threading.Timer(e=>method(),null,Timespan.Zero,TimeSpan.FromHours(24));
So the above line of code would check for the condition for every 24 hours.
My doubt is, what happens to the process in the mean time(like between 24 hours). Does it goes to sleep on its own? if so, is there any way to know if the process is at sleep
Does it goes to sleep on its own?
No, the current thread will continue to run, and do whatever you tell it to do. If you want the thread to sleep you need to tell it to sleep. And this is possibly what you should do for a console program, or trap it in a "press any key to continue" question.
If your application is an UI application there will be a main thread that listens for windows messages, in that case you should rarely if ever use Thread.Sleep on the UI thread.
The timer uses the OS to do the actual waiting, and this will eventually use some kind of hardware to raise timing events. When the timer elapses it will raise the event on the threadpool, so it may run concurrently with the thread that started the timer. Note that there are other timers that work slightly differently.

Multithreading a GUI using backgroundworkers

There is 2 Backgroundworkers in my project:
BGW1: the first worker is used to read data from a controller and convert the data into the right format
BGW2: the second worker is used to pass the converted data and objects to the GUI using the ReportProgress functionality
The entire process needs to be as real time as possible and the messages are coming approx every 0.5 ms. The MainThread becomes flustered pretty quick when it has to update 800 points every 5-10 ms.
This causes the GUI to become unresponsive if i update at a faster rate than 10fps.
A solution i have found online, is this:
Alternate Way of Multithreaded GUI
I have tryed to adopt this methodology to my background workers by setting
// Prevent the framework from checking what thread the GUI is updated from.
theMainForm.CheckForIllegalCrossThreadCalls = false;
in the main form. This allows me to update the gui from a seperate thread not the main thread, from what i understand.
Using this line in the main should mean that i can access the GUI elements from other threads that arent the main thread, and i dont need to use ReportProgress
to update the Chart, so i tried updating the Chart from my DoWork portion of BGW2.
The update works from DoWork, but it seems to still just refer the Data to the MainThread and that thread then updates the chart, which results in an unusable GUI again.
Do i have to get rid of the backgroundworkers completly and only use Threads for the solution from the link to work? Or is there some sort of trick to getting this method to work with backgroundworkers.
Well, don't update that often. Just stick to a fixed refresh rate, and use a ConcurrentQueue to pass the data points between the BackgroundWorker that reads the data, and the GUI that renders it. A simple Timer should work well enough - every five seconds, read everything out of the ConcurrentQueue and update the chart.
Don't update the UI from multiple threads. There's a reason why the checks are there.
One background worker really is enough.
The expensive parts of this operation are;
Synchronizing back to the UI thread
Blocking the worker while you do it.
The solve the performance issue, minimise #1. Don't post every item, post many items every x milliseconds.
In fact, I'd recommend not using a background worker at all - the ReportProgress event blocks your worker thread.
Have you tried to enforce the events being handled? This will empty the events queue so the form becomes responsible for the user. Nevertheless you better go with updating the GUI at a fixed rate, as pointed out by Luaan.

Redrawing windows application

I have a software in C# I'm writing and every time its doing a hard task and I switch windows to let it complete the window screws up. Not sure how to word it but all of the buttons disappear or become "holes" . I know the application is running because the progress bar shows up again after a while. How do I fix this? I've been searching and I'm sure it has something to do with doubleBuffering.
you normally solve this by executing your resource intensive process in a separated thread than the main UI thread, in this way the UI thread can refresh the UI as needed and your long lasting operation is completed in parallel. After the background / worker thread has completed its task the control flow will return to the application.
Things are a bit more complicated when you want to update the status bar in the UI thread from the worked thread, usually you have to use the Invoke methods because you definitely should not even try to access and modify UI controls from another thread.
a bit cheaper method which kind of works but can have some issues from time to time is to include in your long lasting operation a call to Application.DoEvents() from time to time, for example if you are in a loop, every few iterations of the loop (depends on how much time it takes to execute a single iteration and on how many iterations you have in total); this method works and saves you completely from start working with multiple threads but is also considered less reliable.
As LarsTech already pointed out, use the BackgroundWorker-Class, especially for tasks which take longer than just a few seconds.
Make sure to use ReportProgress in your Backgroundworker to notify your Progressbar.
Good links worth studying:
http://www.albahari.com/threading/part3.aspx
http://www.codeproject.com/Articles/99143/BackgroundWorker-Class-Sample-for-Beginners

time or timing in C#, and another question

the question is:
how can i for example every two seconds without user intervention make a label flashes.
like every 2 seconds label.text="". and the next two seconds i do this label1.text="visible"
or changing another property like color or anything.
i give up
could you help me with a basic code, thank you.
You may try using the timer with a 2-second interval. But keep in mind, whenever you play with threads outside of the UI, you need to look in to delegates and BeginInvoke
To accomplish what you're after, you could run it every 1 second, then check against DateTime.Now to see if the clock matches your criteria.
Your question is a bit difficult to understand, but I'll give it my best shot.
From what I understand, you want your code to do something every two seconds. The easiest way to do that is with a timer. The System.Timers.Timer class is useful for that, as well as System.Threading.Timer. Which you use is up to you, but the one in the Threading namespace is a little more primitive.
Timers operate on a ThreadPool, so if you will be manipulating a Windows Form, make sure what you do happens on the GUI thread either by using Control.Invoke for Windows Forms or Dispatcher.Invoke for WPF. Timers are also a little tricky because their Threading Apartment is typically MTA, so if you try to access the clipboard or something like that, you may get errors.
If you want to ensure your timer fires exactly at a certain time, rather than at a specific interval, you could make a timer with a period that starts another timer, or adjusts itself. I would argue that if you are doing something every 2 or 5 seconds do you really need it to happen at a very specific time? Timers, and Windows Time in general isn't specific enough and has small inaccuracies - it will drift over time by a few milliseconds.
What you could do with one thread is something like this :
Sleep 2 seconds
DoAction
Sleep 2 seconds
DoAnotherAction
In a loop.
With 2 threads, I would recommend something like this : C# Running timed job on StackOverflow
Edit : use QuartzNet (tutorial).
A link on StackOverFlow.
The easiest way to do this is with System.Windows.Forms.Timer. You can drop it on your form and set the interval, and create the Tick event handler. The linked documentation has a simple example that you can easily modify to work with your label.
The beauty of using this timer is that it automatically synchronizes with the UI thread, so you don't have to worry about Invoke, BeginInvoke, etc.

Best practice for continual running process in C#

I am working on a project in C#.NET using the .NET framework version 3.5.
My project has a class called Focuser.cs which represents a physical device, a telescope focuser, that can communicate with a PC via a serial (RS-232) port. My class (Focuser) has properties such as CurrentPosition, CurrentTemperature, ect which represents the current conditions of the focuser which can change at any time. So, my Focuser class needs to continually poll the device for these values and update its internal fields. My question is, what is the best way to perform this continual polling sequence? Occasionally, the user will need to switch the device into a different mode which will require the ability to stop the polling, perform some action, and then resume polling.
My first attempt was to use a time that ticks every 500ms and then calls up a background worker which polls for one position and one temperature then returns. When the timer ticks if the background worker isBusy then it just returns and tries again 500ms later. Someone suggested that I get rid of the background worker all together and just do the poll in the timer tick event. So I set the AutoReset property of the timer to false and then just restart the timer every time a poll finishes. These two techniques seemed to behave the exact same way in my application so I am not sure if one is better than the other. I also tried creating a new thread every time I want to do a poll operation using a new ThreadStart and all that. This also seemed to work fine.
I should mention one other thing. This class is part of a COM object server which basically means that the class library that is produced will be called upon via COM. I am not sure if this has any influence on the answer but I just thought I should throw it out there.
The reason I am asking all of this is that all of my test harness runs and debug builds work just fine but when I do a release build and try to make calls to my class from another application, that application freezes up and I am having a hard time determining the cause.
Any advice, suggestions, comments would be appreciated.
Thanks, Jordan
Remember that the timer hides its own background worker thread, which basically sleeps for the interval, then fires its Elapsed event. Knowing that, it makes sense just to put the polling in Elapsed. This would be the best practice IMO, rather than starting a thread from a thread. You can start and stop Timers as well, so the code that switches modes can Stop() the Timer, perform the task, then Start() it again, and the Timer doesn't even have to know the telescope IsBusy.
However, what I WOULD keep track of is whether another instance of the Elapsed event handler is still running. You could lock the Elapsed handler's code, or you could set a flag, visible from any thread, that indicates another Elapsed() event handler is still working; Elapsed event handlers that see this flag set can exit immediately, avoiding concurrency problems working with the serial port.
So it looks like you have looked at 2 options:
Timer. The Timer is non-blocking while waiting (uses another thread), so the rest of the program can continue running and be responsive. When the timer event kicks off, you simply get/update the current values.
Timer + BackgroundWorker. The background worker is also simply a separate thread. It may take longer to actually start the thread than to simply get the current values. Unless it takes a long time to get the current values and causes your program to become unresponsive, this is unnecessary complexity.
If getting values is fast enough, stick to #1 for simplicity.
If getting values is slow, #2 will work but unnecessarily has a thread start a thread. Instead, do it with only a BackgroundWorker (no Timer). Create the BackgroundWorker once and store in a variable. No need to recreate it every time. Make sure to set WorkerSupportsCancellation to true. Whenever you want to start checking values, on your main program thread do bgWorker.RunWorkerAsync(). When you want to stop, do bgWorker.CancelAsync(). Inside your DoWork method, have a loop that checks the values and does a Thread.Sleep(500). Since it's a separate thread, it won't make your program unresponsive. In the loop conditions, also check to see if the polling was cancelled and break out. You'll probably need a way to get the values back to the main thread. You can use ReportProgress() if an integer is good enough. Otherwise you can create an object to hold the content, but make sure to lock (object) { } before reading and modifying it. This is a quick summary, but if you go this route I would recommend you read: http://www.albahari.com/threading/part3.aspx#_BackgroundWorker
Is the process of contacting the telescope and getting the current values actually take long enough to warrant polling? Have you tried dropping the multithreading and just blocking while you get the current value?
To answer your question, however, I would suggest not using a background worker but an actual Thread that updates the properties continuously.
If all these properties are read only (can you set the temp of the telescope?) and there are no dependencies between them (e.g., no transactions are required to update multiple properties at once) you can drop all the blocking code and let your thread update willy-nilly while other threads access the properties.
I suggest a real, dedicated Thread rather than the thread pool just because of a lack of knowledge of what might happen when mixing background threads and COM servers. Also, apartment state might play into this; with a Thread you can try STA but you can't do that with a threadpool thread.
You say the app freezes up in a release build?
To eliminate extra variables, I'd take all the timer/multi-threaded code out of the application(just comment it out), and try it with a straightforward blocking method.
i.e. You click a button, it calls a function, that function hits the COM object for data, and then updates the UI. All in a blocking, synchronous fashion. This will tell you for sure whether it's the multi-threading code that's freezing you up, or if it's the COM interaction itself.
How about starting a background thread with ThreadPool? Then enter a loop based on a bool (While (bContinue)) that loops and does your work and then a Thread.Sleep at the end of the loop - exiting the program would include setting bContinue to false so the thread stops - perhaps hook it up to the OnStop event in a windows service
bool bRet = ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunc));
private void ThreadFunc(object objState)
{
// enter loop
bContinue = true;
while (bContinue) {
// do stuff
// sleep
Thread.Sleep(m_iWaitTime_ms);
}
}

Categories

Resources