I am working on a application that creates a report with pretty complicated graphics, which no doubt takes a lot of time. In order to convince the users that the program is actually working and has not hanged itself up, I thought of using a small window that shows a spinning gif image along with some message asking them to wait for the process to complete.
Everything works as I wanted, except a few minor bugs like the MainForm not getting focus after the WaitForm is closed.
The problems I am facing and don't have a clue about are these -
1. The gif image does not animate. All I can guess is that the WaitForm window is also waiting for the main thread to join the LenghtyOperationThread before animating the gif.
2. I cannot figure out a way to return focus to the MainForm window once the WaitForm window closes.
Help me out? Please?
Thanks for pointing out the errors. Both problems are now solved.
UPDATE. DON'T DO WHAT I DID ABOVE. THIS CODE WILL GIVE YOU Threading and GDI+ exceptions randomly. I am not sure how, but this code also causes the application to slow down after a few hours. Memory and processor usage will remain minimal, as seen in task manager or process hacker.
New code is posted below. Long story short, use a backgroundwoker.
When this code gets executed, main thread will be blocked until the worker thread finishes execution. Which means none of the UI messages will be processed and that might be the reason why you don't see GIF file animating.
I'd offload the work of creating report to to the WaitForm and do a ShowDialog() instead of Show() for displaying the WaitForm. You can modify WaitForm's constructor so that you can pass necessary information required for report generation. This should fix both of your problems.
The report is basically a graphics object (not a physical file) for viewing and printing. It has to be created and displayed in the MainForm, so offloading the task to the WaitForm is not possible.
Also, Using WaitForm.ShowDialog() sort of solves the problem, and is not blocked in the main thread, but then I have no way of closing the WaitForm.
However, you were right about the main thread being blocked. I wanted it to be blocked, until report creation is complete. But I had wrongly assumed that WaitForm.Show() would run in its own thread, like a dialog box.
Thanks for pointing it out. I have the solution now.
1) Run the lengthy thread "Async". As is now, I can see how "createreport" is running on it's own thread, but not the lengthy operation.
2) Try[^] Form.Show(this). Once the Window closes, focus within the app should move to it's owner (if the app has focus).
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
1. Right on the money. CreateReport() is running on its own thread. But, WaitForm.Show() was not. The main thread blocked it from doing anything. And when as soon as it gets to do something, it was closed. I had stupidly assumed that Form.Show() runs on its own thread, like Form.ShowDialog(). Problem was I had no way of closing the DialogBox after CreateReport was done.
2. Taking care of the first problem took care of the second. Dark magic at work I say. .
Thanks for the idea of 'async' though. Couldn't use it because app has to run on .NET 3.5. So, created a new thread to show the WaitForm. Worked like a charm.
WRONG! You NEVER put any UI on the a seperate thread. What you did was put the UI on a seperate thread and then launched the long running work in yet another thread.
The way you've done it will appear to work fine but your code WILL run into problems every now and then that you can't replicate and will have a nasty time debugging. DO NOT PUT ANY UI IN A BACKGROUND THREAD!
Your long running work gets put on a background thread, such as using a BackgroundWorker, and then that frees up your UI thread to, well, update the UI. BackgroundWorker exposes a couple of events you can use to manage updating the UI without resorting to putting the UI in another thread.
Well, the grossly simplified explanation is that Windows GDI library code that Graphics uses and all Forms and Controls use to draw themselves is not "thread-safe". The calls to various drawing and resource functions can step all over each other in very unsafe ways.
You can try to synchronize all of your resource and drawing calls, but the problem is that your application is not the only one using GDI when it's running, so it's nearly impossible to get a reliable multithreaded graphic routine running using GDI. The only reliable way to do multithreading GDI is to marshall all your control manipulation and drawing to methods on the UI thread.
hi to all..i need some help on how to access my ip camera in order to display stream on picturebox..please do help me... my camera has an ip 192.168.8.1..it can also be accessed through firefox by http://192.168.8.1 ..this is also my code,when i click the button, the picturebox should show the stream from the camera, but nothing happens..i am also using aforge.net library..
please check my code.. what do i missed? any help is greatly appreciated..thank you..
public partial class Form1 : Form
MJPEGStream stream = new MJPEGStream("http://192.168.8.1");
The Jet provider won't work if you're running this code on a 64-bit machine. Jet is 32-bit only.
So, you either have to install the 64-bit ACE engine, downloadable from here[^] or go into your project properties and set the Target CPU to "x86" instead of "AnyCPU". That will force your code to run as a 32-bit application.