I wrote a function that does alot of mathematical operations and it takes about 10 minutes to finish its work. I tried to call this function via a button on a form (Windows forms application). But the problem now is during the 10 minutes, the main form stops to respond till the function is finishing its work.
How can i solve this... any idea!
You might assign a new thread for the calculations so that the form would not have to wait for the calculation to finish to continue execution (i.e. listening to and responding to events etc.)
The problem is that, while your 10 minute function is working, the rest of the program is not executed. In particular, it cannot execute the rendering. (i.e. making your form respond).
The solution is to use threads.
As already mentioned you should assign long running tasks to a worker thread or a threadpool thread.
Keep in mind that there are limited numbers of threadpool thread. ALso Windows forms is not thread safe so you should not be directly updating the form from the created thread. You can make use of InvokeRequired.
In this case better to use BackgroundWorker class. Details in following link.
http://stuff.seans.com/2009/05/21/net-basics-do-work-in-background-thread-to-keep-gui-responsive/
Related
I know very similar questions have been asked before, but I am unable to find an answer for my specific problem. I have a main (GUI) thread which upon button press initializes a worker thread to perform some analysis. I am using signals and slots to communicate between my worker thread and my GUI thread (i.e. when the thread starts and when it finishes), but I need to go deeper than that. My worker thread actually calls another class in a separate implementation file which then iterates through a series of calculations which are sent to std::cout for each iteration (as the code used to be a console application for which I am now writing a GUI). I am trying to feed those outputs for each iteration back into my GUI thread so that my text browser is updated in real time as my code iterates. The problem is, when I emit a signal from the class my worker thread calls, it is not picked up by the GUI thread. I do not get any errors. Does anyone have any suggestions on how to transmit a signal to the GUI from a class that my worker thread is calling? I can post code as required, but I'm not sure what would be most helpful to see and my code is quite extensive (it's an aircraft performance application). Any help would be greatly appreciated. Thank you kindly!
1) Make sure the connect() call for connecting you signal returns true. If it does not, qdebug output usually tells you what is wrong
2) You should use the QueuedConnection type (the default (Auto) should work also)
I have a time consuming process which runs with an NSOperation.
I now need user's choice to choose between different subprocesses.
I need to stop the process until the user respond to the question.
How can I do this from an NSOperation?
Thanks
It should just be a matter of creating an NSAlert and calling runModal on it, making sure you're on the main thread. Have you tried that?
Perhaps in the method where you are creating the NSAlert, you can have assert([NSThread isMainThread]) at the top of the method and I think that this will assure that this method get executed on the main thread. I hope this helps!
I have a application in which i am sending a SMS to the Server which will return the result as an SMS. So i have put a Message Intercepter with the Event Handler. The Problem is that Once i send the request i have to wait for 30 seconds before i go ahead with the operation. How do i make my application wait till that. if i use the Thread.sleep it is making the whole application sleep and i am not getting any response out there.
Any idea how to tackle this
Thanks in Advance
Regards
Biju
What I assume you are trying to do is prevent the user from advancing until they receive a valid response from SMS, as some kind of authentication with a timeout of 30 seconds if the response was not received.
To do this, you could display a modal dialog that just displays the "Waiting for SMS Response.." message and close the dialog once 30 seconds have elapsed (using a Timer) or a response is received from SMS.
The event should fire asynchronously, so your program continues. You can have the event handler set a flag to continue on whatever path your program is taking.
also, as a side note, if you ever find yourself thinking "gee, Thread.Sleep(1000) would work great here" take a step back and examine the situation. Most of the time, you can do it asynchronously with events.
It sounds like you could use a timer of some kind. If you need to execute your code within the UI thread, you could use a System.Windows.Forms.Timer; if you're happy with it executing in a thread pool thread you could use System.Threading.Timer or System.Timers.Timer.
I don't know offhand which of these are available in the Compact Framework, but I'd expect at least one of them to be.
If they're really not available, one option which is kinda hacky but would work is to create a new thread which just sleeps for 30 seconds and then either executes the code you need or marshals to the UI thread (using Control.Invoke/BeginInvoke) to execute there if necessary. It's about as crude a timer as you can get, but it should work.
There is a very common task I face again. I have already solved this a couple of times, but now I am looking for a more "elegant" way - can you deliver some input?
Situation:
I have a Method which I would like to run "semi async". In other words: Start it and wait a given time x. If the method is not finished by then ("timed out"), I want to continue my code with some cleanup procedures.
Solutions so far:
Use an AutoResetEvent (or
ManualResetEvent) combined with an
annonymus method using
.WaitOne(x).
Use a Thread/BackgroundWorker
combined with a Timer. If the timer
hits its handler before the thread stops it, the therad is timed out.
Both appraochs work fine but I imagine there is a better way with 4.0.
Suggestions?
Does Task.Wait(Timeout) from the Task Parallel Library do what you want? (You may wish to combine this with cancellation tokens to cancel the task after the timeout occurs.)
Actually i am using this code and works ok, but i 'am wondering if is the correct way.
while WaitForSingleObject(MyThread.Handle, 0) = WAIT_TIMEOUT do
Application.ProcessMessages;
ShowMessage('i am done');
The VCL TThread class has its own WaitFor() method that pumps the main message queue internally when called within the main thread context:
MyThread.WaitFor;
ShowMessage('i am done');
Calling Application.ProcessMessages is generally considered a code smell. Let your main thread idle if it's got nothing to do.
If you ran a company and needed one of your workers to run to the store and grab some much-needed supplies, would you then pace by the door until he got back, or would you prefer to sit in your office and rest and wait for him, and find out that the supplies are here because you hear him walk through the door? Either way, he'll take the same amount of time, but the first way's gonna wear your legs out.
Similarly, instead of having your UI watch the thread, have the thread report back to the UI. One way to do this is to have the thread use PostMessage to send a custom message to the form that launched it once it's finished, and put a message handler on the form to respond to it.
It looks correct (if correct means it do the work). What I would change is to wait for a bit more time (50ms looks good to maintain the application responsive) while not eating CPU.
while WaitForSingleObject(MyThread.Handle, 50) = WAIT_TIMEOUT do
Application.ProcessMessages;
ShowMessage('i am done');
Sure there are other ways to do it... <joke>but I usually apply one of the main engineering principles:
if it works, don't touch it!</joke>
I agree with Mason Wheeler's remark, the main thread is best left to do its job, but I would suggest using the OnTerminate event on the thread. It is more 'Delphi natural' and the internal logic does the PostMessage bit for you. Since TThread is not a component, you can't view it in the object inspector and have to write and attach an event handler yourself. It gets called (in the main thread!) after the thread has completed/terminated.
While it looks okay, like jachguate I would use a bigger time-out value than 0 too. If you use WaitForSingleObject(MyThread.Handle, 100) then the main thread will wait a bit longer, thus eating up less CPU cycles.
A better solution would be the use of messages, though. Your application starts the thread and then puts all controls in disabled mode. The thread then executes and when it's finished, use SendMessage or PostMessage to the main window to notify it that the thread is done again. Then your application will just enable every control (and whatever else) again. This has as advantage that you keep the "natural" messageloop for the application alive, instead of running your own messageloop with this solution.Unfortunately, the message-method has one drawback: if the thread crashes then no message will be sent back, so a backup plan would be practical. For example, by adding a timer control to your mainform which checks every second if the thread is still alive. If not, it too would just activate the form again, disabling itself again.