http://www.daniweb.com/software-development/vbnet/threads/147601/not-responding-message#
http://msdn.microsoft.com/en-us/magazine/cc164037.aspx (Practical Multithreading for Client Apps)
Here's a tip:
Show wait cursor:
Me.Cursor = Cursors.WaitCursor
and after the work is done return it to normal:
Me.Cursor = Cursors.Default
If you have a statusbar in your form you may display text: "Loading..." or something like that.
And the most important thing. If you have some long lasting loop in your code, call
Application.DoEvents()
every once in a while so the message queue won't get "stuck" (prevents Not Responding message).
But do be careful when you are using "DoEvents()" - http://stackoverflow.com/questions/5181777/use-of-application-doevents
Application.DoEvents()
is used to pump messages in the UI thread when performing a long-running task in the UI thread. This is almost always not the best way to do things. It is much better to do extensive tasks in another thread. Look here for more details.
Multiple Threading Solution:
1.Calls to ThreadPool.QueueUserWorkItem are simple to perform and make better use of system resources than the repeated creation of manual threads.
2.Invoke method is to marshal a call from any thread to the thread that implements the message pump for the control or form. Invoke is one of the very few methods on controls that is safe to call from any thread because it's implemented using the Win32 PostMessage API.
3. use AutoResetEvent to implement cancel operation
Sample Code:
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Microsoft.VisualBasic;
class App {
// Application entry point
public static void Main() {
// Run a Windows Forms message loop
Application.Run(new CancelableMultiThreadedForm());
}
}
// A Form-derived type
class CancelableMultiThreadedForm : Form {
// Constructor method
public CancelableMultiThreadedForm() {
// Create a text box
text.Location = new Point(10, 10);
text.Size = new Size(50, 20);
Controls.Add(text);
// Create a button
button.Text = "Beep";
button.Size = new Size(50, 20);
button.Location = new Point(80, 10);
// Register Click event handler
button.Click += new EventHandler(OnClick);
Controls.Add(button);
// Create a cancel button
cancelButton.Text = "Cancel";
cancelButton.Size = new Size(50, 20);
cancelButton.Location = new Point(80, 35);
// Register Click event handler
cancelButton.Click += new EventHandler(OnCancel);
Controls.Add(cancelButton);
EnableControls(true);
// Cache a delegate for repeated reuse
enableControls = new BooleanCallback(EnableControls);
}
// Method called by the cancelButton's Click event
void OnCancel(Object sender, EventArgs args) {
// Let it be known that we are canceling!
cancelOperation.Set();
}
// Method called by the button's Click event
void OnClick(Object sender, EventArgs args) {
// Get an int from a string
Int32 count = 0;
try { count = Int32.Parse(text.Text); } catch (FormatException) {}
// Count to that number
EnableControls(false);
WaitCallback async = new WaitCallback(Count);
ThreadPool.QueueUserWorkItem(async, count);
}
// Async method beeps once per second
void Count(Object param) {
Int32 seconds = (Int32) param;
// Beep the requested number of times
for (Int32 index = 0; index < seconds; index++) {
Interaction.Beep();
if (cancelOperation.WaitOne(1000, false)) {
break;
}
}
// EnableControls has been enhanced to auto-proxy its call to
// the GUI thread, and so can be called safely from any thread
EnableControls(true);
}
void EnableControls(Boolean enable) {
// EnableControls makes sure that it is being called on
// the GUI thread using InvokeRequired and BeginInvoke
if (InvokeRequired) {
BeginInvoke(enableControls, new Object[]{enable});
return;
}
button.Enabled = enable;
text.Enabled = enable;
cancelButton.Enabled = !enable;
}
// An AutoResetEvent used to indicate cancellation
AutoResetEvent cancelOperation = new AutoResetEvent(false);
// A delegate type and matching field
delegate void BooleanCallback(Boolean enable);
BooleanCallback enableControls;
// Some private fields by which to reference controls
Button button = new Button();
TextBox text = new TextBox();
Button cancelButton = new Button();
}