i have an application in c# windows forms (fw4.0) and i have a method that creates a json string and send via post to an action method in a web page. I don't know how much it takes, but i want to show a progress bar while the method is executing. How can i do it?
One idea i have is to perform a counter while the method is running and show it to the user, but i don't know how.. it must be in another thread? how?
I dont have any more helpful information to provide.. i hope you can help me!
Thanks!
Use the background worker to prevent blocking the UI and to report progress.
You can report progress based on two values:
prob_time -- the most probable amount of time the action will take to complete;
max_time -- the maximum amount of time you are willing to wait before considering that the action failed;
You can make the progress bar get to a certain point(e.g. 80%) in prob_time, then to 100% in (max_time-prob_time).
If the action completes faster that max_time, you make the progress jump to 100% and report "Success", otherwise report "Failure"
Finally i did!
I have to use 2 background workers.. this is what i did..
backgroundWorker1: performs the post method.
backgroundWorker2: performs a TimeSpan counter.
when backgroundWorker2 starts, sets a TimeSpan in 0 and in the DoWork, if the backgroundWorker1 CancellationPending is false, then i report progress in backgroundWorker2.
When the post method finish, i set backgroundWorker1 to CancelAsync, so the backgroundWorker2 will terminate to.
I think that was my best solution.
Related
I'm working on an application that processes (possibly large reaching one or two million lines) text (in tab separated form) files containing detail of items and since the processing time can be long I want to update a progress bar so the user knows that the application didn't just hang, or better, to provide an idea of the remaining time.
I've already researched and I know how to update a simple progress bar but the examples tend to be simplistic as to call something like progressBar.setProgress(counter++, 100) using Timer, there are other examples where the logic is simple and written in the same class. I'm also new to the language having done mostly Java and some JavaScript in the past, among others.
I wrote the logic for processing the file (validation of input and creation of output files). But then, if I call the processing logic in the main class the update will be done at the end of processing (flying by so fast from 0 to 100) no matter if I update variables and try to dispatch events or things like that; the bar won't reflect the processing progress.
Would processing the input by chunks be a valid approach? And then, I'm not sure if the processing delay of one data chunk won't affect the processing of the next chunk and so on, because the timer tick is set to be 1 millisecond and the chunk processing time would be longer than that. Also, if the order of the input won't be affected or the result will get corrupted in some way. I've read multithreading is not supported in the language, so should that be a concern?
I already coded the logic described before and it seems to work:
// called by mouse click event
function processInput():void {
timer = new Timer(1);
timer.addEventListener(TimerEvent.TIMER, processChunk);
timer.start();
}
function processChunk(event:TimerEvent):void {
// code to calculate start and end index for the data chunk,
// everytime processChunk is executed these indexes are updated
var dataChunk:Array = wholeInputArray.splice(index0, index1);
processorObj.processChunk(dataChunk)
progressBar.setProgress(index0, wholeInputArray.length);
progressBar.label = index0 + " processed items";
if(no more data to process) { // if wholeInputArray.length == index1
timer.stop();
progressBar.setProgress(wholeInputArray.length, wholeInputArray.length);
progressBar.label = "Processing done";
// do post processing here: show results, etc.
}
}
The declaration for the progress bar is as follows:
<mx:ProgressBar id="progressBar" x="23" y="357" width="411" direction="right"
labelPlacement="center" mode="manual" indeterminate="false" />
I tested it with an input of 50000 lines and it seems to work generating the same result as the other approach that processes the input at once. But, would that be a valid approach or is there a better approach?
Thanks in advance.
your solution is good, i use it most of time.
But multithreading is now supported on AS3 (for desktop and web only for the moment).
Have a look at: Worker documentation and Worker exemple.
Hope that helps :)
may I ask if this Timer AS IS is the working Timer ??? because IF YES then you are in for a lot of trouble with your Application in the long run! - re loading & getting the Timer to stop, close etc. The EventListener would be incomplete and would give problems for sure!
I would like to recommend to get this right first before going further as I know from experience as in some of my own AIR Applications I need to have several hundred of them running one after another in modules as well as in some of my web Apps. not quiet so intense yet a few!
I'm sure a more smother execution will be the reward! regards aktell
Use Workers. Because splitting data into chunks and then processing it is a valid but quite cumbersome approach and with workers you can simply spawn a background worker, do all the parsing there and return a result, all without blocking GUI. Worker approach should require less time to do parsing, because there is no need to stop parser and wait for the next frame.
Workers would be an ideal solution, but quite complicated to set up. If you're not up to it right now, here's a PseudoThread solution I use in similar situations which you can probably get up and running in 5 minutes:
Pseudo Threads
It uses EnterFrame events for balancing between work and letting the UI does its thing and you can manually update the progress bar within your 'thread' code. I think it would be easily adapted for your needs since your data is easily sliced.
Without using Workers (which it seems you are not yet familiar with) AS3 will behave single threaded. Your timers will not overlap. If one of your chunks takes more than 1s to complete the next timer event will be processed when it can. It will not queue up further events if it takes more than your time period ( assuming your processing code is blocking).
The previous answers show the "correct" solution to this, but this might get you where you need to be faster.
I have a large query that needs to be loaded into memory. This query takes about 30 seconds to open. It loads immediately after the application starts, only once. During this time the application hangs. What I need to do is to update a progress bar, during the 30 seconds. I've tried to create a new thread to update the progress bar, but it will only update after the query is opened. Can anyone point a simple way to do this?
I've created a thread class:
type
TMyThread = class(TThread)
private
fLowerLimit: Integer;
fUpperLimit: Integer;
I'm creating an instance of the thread class:
CountingThread := TMyThread.Create(0, 300, True);
CountingThread.Resume;
//
SplashDlg.Show;
Inside the thread I'm just updating the progress bar:
procedure TMyThread.UpdateMainThread;
begin
SplashDlg.ProgressBar1.Position:= SplashDlg.ProgressBar1.Position+1;
MyDebug('UpdateMainThread:'+ IntToStr(SplashDlg.ProgressBar1.Position));
end;
The thread hangs while the query is opening.
It's better to paste some code here if you wish to get a more exact answer.
There are 2 ways in witch you can process data and have the UI responsive.
You can use Application.ProcessMessages in your loop.
Or the thread solution that you already approached.
The problem is I don't think you have a loop you are using a component and if that component doesn't call a method to show a progress you can't estimate how much time the query will take to complete. So either you show a loading... screen while te query executes without a progressbar or you tell us more about what you use for the query.
Hope it helps
You're doing it the other way around.
The UI is bound to the application main thread, so you always take care of the UI in the main thread, and do the real job in a worker thread (from there the worker name).
The way you're asking the question, you're already dealing with threads, so, just change your point of view and perform the heavy SQL load in a secondary thread while keeping your UI responsive and updated in the, now non-busy, main thread.
As for the 30 seconds wait time, really, if you can't determine exactly the load time is better to not use a progress bar, since we all hate that liar bars who don't reflect the real state of things. Your bar sometimes will show 50% and suddenly goes to 100%... or it may reach 100% while in fact the real thing is going to take ages to complete (heavy load on the server, slow network, and 1,000 other factors).
Nowadays, we all are used to the just wait indicators, like this:
When you see this, you know it is working, and you just have to wait until it completes.
Can someone recommend a straight forward way of adding some type of graphical notification (status bar, spinning clocks, etc...) to my wx.Python gui application? Currently, it searches logs on a server for unique strings, and often times takes upwards to 3-4 minutes to complete. However, it would be convenient to have some type of display letting a user know that the status of the job towards finishing/completion. If I added a feature like this, I'm not sure, but I'm afraid I may have to look at using threads ... and I'm a complete newbie to Python? Any help and direction will be appreciated.
Yes, you'd need to use threads or queues or something similar. Fortunately, there are some excellent examples here: http://wiki.wxpython.org/LongRunningTasks and this tutorial I wrote is pretty straight-forward too: http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
Using threads isn't that hard. Basically you put the long running part in the thread and every so often, you send a status update to your GUI using a thread-safe method, like wx.PostEvent or wx.CallAfter. Then you can update your statusbar or a progress bar or whatever you're using.
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/
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.