How to Display a Loading Control While a Process Is Waiting for Be Finished

How can I display a loading control while a process is waiting for be finished?

You create a thread, which simply sets two properties and then ends. The t.Abort will probably do nothing, since the thread will have been exited by that time. Even worse, you import the excel file on the UI thread, which blocks any animation and freezes the complete UI.

This is how you should make it:

Remark: Of course if your form is responsive, you must disable/enable the controls and prepare to the case what happens if your form is being closed during the load.

1. Using threads

If you really want to explicitly use threads, do it like this:

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private Thread workerThread = null;

private void btnImport_Click(object sender, EventArgs e)
{
// start the animation (I used a progress bar, start your circle here)
progressBar1.Visible = true;
progressBar1.Style = ProgressBarStyle.Marquee;

// start the job and the timer, which polls the thread
btnImport.Enabled = false;
workerThread = new Thread(LoadExcel);
workerThread.Start();
timer1.Interval = 100;
timer1.Start();
}

private void LoadExcel()
{
// some work takes 5 sec
Thread.Sleep(5000);
}

private void timer1_Tick(object sender, EventArgs e)
{
if (workerThread == null)
{
timer1.Stop();
return;
}

// still works: exiting
if (workerThread.IsAlive)
return;

// finished
btnImport.Enabled = true;
timer1.Stop();
progressBar1.Visible = false;
workerThread = null;
}
}

2. Background worker

The BackgroundWorker can throw an event when it is finished:

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.DoWork += BackgroundWorker1_DoWork;
backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted;
}

private void btnImport_Click(object sender, EventArgs e)
{
// start the animation
progressBar1.Visible = true;
progressBar1.Style = ProgressBarStyle.Marquee;

// start the job
btnImport.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}

private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
LoadExcel();
}

private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
btnImport.Enabled = true;
progressBar1.Visible = false;
}

private void LoadExcel()
{
// some work takes 5 sec
Thread.Sleep(5000);
}
}

3. Using async-await

This is the simplest one.

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private async void btnImport_Click(object sender, EventArgs e)
{
// start the waiting animation
progressBar1.Visible = true;
progressBar1.Style = ProgressBarStyle.Marquee;

// simply start and await the loading task
btnImport.Enabled = false;
await Task.Run(() => LoadExcel());

// re-enable things
btnImport.Enabled = true;
progressBar1.Visible = false;
}

private void LoadExcel()
{
// some work takes 5 sec
Thread.Sleep(5000);
}
}

Wait until form is finished loading

try to use the shown event something like this

 public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Shown += new System.EventHandler(this.Form1_Shown);
}

private void Form1_Shown(object sender, EventArgs e)
{

}
}

hope this help

Best way to display a progress form while a method is executing code?

A BackgroundWorker is a great way to perform a long running operation without locking the UI thread.

Use the following code to start a BackgroundWorker and display a loading form.

// Configure a BackgroundWorker to perform your long running operation.
BackgroundWorker bg = new BackgroundWorker()
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);

// Start the worker.
bg.RunWorkerAsync();

// Display the loading form.
loadingForm = new loadingForm();
loadingForm.ShowDialog();

This will cause the following method to be executed on a background thread. Note that you cannot manipulate the UI from this thread. Attempting to do so will result in an exception.

private void bg_DoWork(object sender, DoWorkEventArgs e)
{
// Perform your long running operation here.
// If you need to pass results on to the next
// stage you can do so by assigning a value
// to e.Result.
}

When the long running operation completes, this method will be called on the UI thread. You can now safely update any UI controls. In your example, you would want to close the loading form.

private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Retrieve the result pass from bg_DoWork() if any.
// Note, you may need to cast it to the desired data type.
object result = e.Result;

// Close the loading form.
loadingForm.Close();

// Update any other UI controls that may need to be updated.
}

Create a loading bar

Putting a Thread.Sleep (or any long-running piece of code) in your event handler will block the UI until that event handler is done running its code.

You have to put such code in a BackgroundWorker, Thread or Task and run that code asynchronously. In that way, the code can run independently from the UI, which will make the UI responsive.

How do I show a Loading . . . please wait message in Winforms for a long loading form?

Using a separate thread to display a simple please wait message is overkill especially if you don't have much experience with threading.

A much simpler approach is to create a "Please wait" form and display it as a mode-less window just before the slow loading form. Once the main form has finished loading, hide the please wait form.

In this way you are using just the one main UI thread to firstly display the please wait form and then load your main form.

The only limitation to this approach is that your please wait form cannot be animated (such as a animated GIF) because the thread is busy loading your main form.

PleaseWaitForm pleaseWait=new PleaseWaitForm ();

// Display form modelessly
pleaseWait.Show();

// ALlow main UI thread to properly display please wait form.
Application.DoEvents();

// Show or load the main form.
mainForm.ShowDialog();

Show Loading animation during loading data in other thread

When the form is frozen, it means the UI thread is too busy and so even if you try to show a loading animation, it will not animate. You should load data asynchronously.

You can have an async method which returns Task<DataTable> like the GetDataAsync method which you can see in this post. Then call it in an async event handler. In the event handler, first show the loading image, then load data asynchronously and then hide the loading image.

You can simply use a normal PictureBox showing a gif animation as loading control. Also you may want to take a look at this post to show a transparent loading image.

Sample Image

public async Task<DataTable> GetDataAsync(string command, string connection)
{
var dt = new DataTable();
using (var da = new SqlDataAdapter(command, connection))
await Task.Run(() => { da.Fill(dt); });
return dt;
}

private async void LoadDataButton_Click(object sender, EventArgs e)
{
loadingPictureBox.Show();
loadingPictureBox.Update();
try
{
var command = @"SELECT * FROM Category";
var connection = @"Your Connection String";
var data = await GetDataAsync(command, connection);
dataGridView1.DataSource = data;
}
catch (Exception ex)
{
// Handle Exception
}
loadingPictureBox.Hide();
}

Display loading content/image while waiting

When you say displaying loading message, I interpret that you're using ajax. In ajax start you can display that image, and in ajax complete callback you can hide the loading image. Please provide some code examples if possible.

In case if jQuery ajax, you can use:

$('#loaderImage').show();
$.ajax({
// Other ajax parameters
success: function () {
// hiding the image here
$('#loaderImage').hide();
}
});

How can I create a Please Wait, Loading... animation using jQuery?

You could do this various different ways. It could be a subtle as a small status on the page saying "Loading...", or as loud as an entire element graying out the page while the new data is loading. The approach I'm taking below will show you how to accomplish both methods.

The Setup

Let's start by getting us a nice "loading" animation from http://ajaxload.info
I'll be using Sample Image

Let's create an element that we can show/hide anytime we're making an ajax request:

<div class="modal"><!-- Place at bottom of page --></div>

The CSS

Next let's give it some flair:

/* Start by setting display:none to make this hidden.
Then we position it in relation to the viewport window
with position:fixed. Width, height, top and left speak
for themselves. Background we set to 80% white with
our animation centered, and no-repeating */
.modal {
display: none;
position: fixed;
z-index: 1000;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba( 255, 255, 255, .8 )
url('http://i.stack.imgur.com/FhHRx.gif')
50% 50%
no-repeat;
}

/* When the body has the loading class, we turn
the scrollbar off with overflow:hidden */
body.loading .modal {
overflow: hidden;
}

/* Anytime the body has the loading class, our
modal element will be visible */
body.loading .modal {
display: block;
}

And finally, the jQuery

Alright, on to the jQuery. This next part is actually really simple:

$body = $("body");

$(document).on({
ajaxStart: function() { $body.addClass("loading"); },
ajaxStop: function() { $body.removeClass("loading"); }
});

That's it! We're attaching some events to the body element anytime the ajaxStart or ajaxStop events are fired. When an ajax event starts, we add the "loading" class to the body. and when events are done, we remove the "loading" class from the body.

See it in action: http://jsfiddle.net/VpDUG/4952/



Related Topics



Leave a reply



Submit