Undoubtedly many of you have encountered the dreaded “Application Not Responding” message, programmers and non-programmers alike.

In general, this is caused by the OS misinterpretation of long delays in form refresh, even though these can easily be caused by a long running process, or any running process longer than a couple seconds actually.

If this is happening in your application after clicking on a button or event fires, a quick solution would be the easy one-liner below:

Application.DoEvents();

However, to really understand why this happening, remember that all processes (may) contain multiple threads.

In the case of your typical quick shot solution that you put together in VS in no-time, you’re likely only using a single thread.

This thread is used not only to run the processes in your application, but also to update the form window including drawing the fields and various controls on the form.

The best solution to this would really be to create a separate thread and pass off the work of your long running function to this thread.

When the work is finished, it will update our main thread (the form thread) that it has completed which we can intercept with a delegate, and notify the user of success or failure.

See snippet below.

private BackgroundWorker hardworker; //this guys works hard!
private System.Timers.Timer lazyworker; //notice how this could also be achieved with thread/timer

protected void btnDoAlotOfWork_Click() {
//lets see who accomplishes more!
ClockInLazyWorker();
ClockInHardWorker();
}

private void ClockInLazyWorker() {
lazyworker = new System.Timers.Timer(); //not to be confused with forms timer
lazyworker.Interval = 1000; //time in milliseconds. 10 seconds is lazy for a computer!
            lazyworker.Elapsed += new System.Timers.ElapsedEventHandler(LetsGetAMoveOnIt());
}

private void ClockInHardWorker() {
hardworker= new BackgroundWorker();
            mCopier.DoWork += DoWork; //all the heavy lifting is done here
            mCopier.RunWorkerCompleted += WorkCompleted();
            mCopier.WorkerSupportsCancellation = true;
            OnError += ProblemWithWork();
}

//motivational function name made especially for our lazy worker
private void LetsGetAMoveOnIt() {
//do something that takes a long time
//if the data you operate on is the same as used by another thread or the form thread, make sure you wrap this block in a synclock or use a bool to track when work is in process
}

//created separate function for the background worker, and also to avoid synclock issues since there are two new active threads
private void DoWork() {
//if the data you operate on is the same as used by another thread or the form thread, make sure you wrap this block in a synclock or use a bool to track when work is in process. same goes for timer.
}

private void WorkCompleted() {
//all finished
}

private void ProblemWithWork() {
//hopefully not an injury on the job! that's workmans comp!
}

Alot more code than simply “Application.DoEvents”.. but do not underestimate the power of multiple threads!

Ronnie Diaz Avatar

Published by

Leave a comment