Avoid (Not Responding) message at Client Application

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:

 
  1. Me.Cursor = Cursors.WaitCursor


and after the work is done return it to normal:

 
  1. 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

 
  1. 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();
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值