bar - progress dialog c#
¿Cómo puedo mostrar un control de carga mientras un proceso está esperando a que finalice? (2)
Crea un hilo, que simplemente establece dos propiedades y luego termina.
El
t.Abort
probablemente no hará nada, ya que el hilo habrá salido para ese momento.
Peor aún, importa el archivo de Excel en el hilo de la interfaz de usuario, que bloquea cualquier animación y congela la interfaz de usuario completa.
Así es como debes hacerlo:
Observación: Por supuesto, si su formulario responde, debe deshabilitar / habilitar los controles y preparar para el caso lo que sucede si su formulario se cierra durante la carga.
1. Usando hilos
Si realmente quieres usar hilos explícitamente, hazlo así:
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. Trabajador de antecedentes
BackgroundWorker
puede lanzar un evento cuando haya terminado:
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. Usando async-await
Este es el más simple.
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);
}
}
Decidí usar este componente de terceros para hacer un control de carga simple en mi formulario de Windows.
http://www.codeproject.com/Articles/14841/How-to-write-a-loading-circle-animation-in-NET
Esto funciona bien cuando se activa y desactiva cambiando la propiedad "Activo" a verdadero o falso en una sola solicitud (una por vez). El problema es cuando un proceso está esperando ser servido, y pretendo activar el control de carga antes de que comience el proceso y apagarlo cuando "creo" que el proceso tiene que finalizar. Cuando lo hago, la carga de la imagen se muestra como una imagen estática. (Sin animación).
Lo siento por esta pregunta, soy nuevo en C #. Pero creo que necesito usar hilos o algo similar.
Entonces mi código general es este:
using [libraries here]...;
namespace [namespace here]
{
Public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.loadingCircle1.Visible = false;
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(showLoading));
this.loadingCircle1.Visible = true;
t.Start();
//Import an Excel
t.Abort();
}
public void showLoading()
{
loadingCircle1.Active = true;
loadingCircle1.RotationSpeed = 10;
}
}
}
Pero Always the Loading se muestra como una imagen estática sin la animación.
Recomiendo usar async / await (para C # 5.0):
private void button1_Click(object sender, EventArgs e){
ImportAsync();
}
private async Task ImportAsync(){
// UI-thread
showLoading();
this.loadingCircle1.Visible = true;
// wait until task will be finished
await Task.Run(() => {
// different non-blocking thread for all the hard work, but without UI-stuff
// import an Excel
});
// going back to UI-thread
this.loadingCircle1.Visible = false;
}