This can be achieved with Threading in windows forms
1) Never invoke any method or property on a control created on another thread other than Invoke, BeginInvoke, EndInvoke or CreateGraphics, and InvokeRequired.
Each control is effectively bound to a thread which runs its message pump. If you try to access or change anything in the UI (for example changing the Text property) from a different thread, you run a risk of your program hanging or misbehaving in other ways. You may get away with it in some cases, but only by blind luck. Fortunately, the Invoke, BeginInvoke and EndInvoke methods have been provided so that you can ask the UI thread to call a method for you in a safe manner.
2) Never execute a long-running piece of code in the UI thread.
If your code is running in the UI thread, that means no other code is running in that thread. That means you won't receive events, your controls won't be repainted, etc. This is a very Bad Thing.
So, if you have a piece of long-running code which you need to execute, you need to create a new thread to execute it on, and make sure it doesn't directly try to update the UI with its results. The interesting bit is - invoking a method on the UI thread in order to update the UI.
Each control is effectively bound to a thread which runs its message pump. If you try to access or change anything in the UI (for example changing the Text property) from a different thread, you run a risk of your program hanging or misbehaving in other ways. You may get away with it in some cases, but only by blind luck. Fortunately, the Invoke, BeginInvoke and EndInvoke methods have been provided so that you can ask the UI thread to call a method for you in a safe manner.
There are two different ways of invoking a method on the UI thread, one synchronous (Invoke) and one asynchronous (BeginInvoke). They work in much the same way - you specify a delegate and (optionally) some arguments, and a message goes on the queue for the UI thread to process. If you use Invoke, the current thread will block until the delegate has been executed. If you use BeginInvoke, the call will return immediately. If you need to get the return value of a delegate invoked asynchronously, you can use EndInvoke with the IAsyncResult returned by BeginInvoke to wait until the delegate has completed and fetch the return value.
MethodInvoker is just a delegate which takes no parameters and returns no value (like ThreadStart),
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
namespace DelegateUIResponsive
{
public class ClsDelegateUIResponsive : System.Windows.Forms.Form
{
delegate void UpdateStatusDelegate (string Msg);
private System.Windows.Forms.Label lblStatus; //Displays status on the window.
private System.ComponentModel.Container components = null;
private ClsDelegateUIResponsive()
{
InitializeComponent();
MethodInvoker mi = new MethodInvoker(StartThread); // New thread.
mi.BeginInvoke(null, null);
}
[STAThread]
static void Main()
{
Application.Run(new ClsDelegateUIResponsive());
}
private void StartThread()
{
for (int i = 0; i < 10; i++)
{
ShowProgress("The counter is : " + i.ToString());
Thread.Sleep(1000);
}
}
private void ShowProgress(string Msg)
{
// We're not in the UI thread, so we need to call BeginInvoke
if (InvokeRequired)
{
BeginInvoke(new UpdateStatusDelegate(ShowProgress), new Object[]{ Msg });
return;
}
this.lblStatus.Text = Msg;
}
}
}
No comments:
Post a Comment