Progressbar, Begininvoke, асинхронный метод

  • Автор темы EuGenius
  • Дата начала
E

EuGenius

Гость
#1
Окно во время заполнения прогрессбара не реагирует на действия пользователя, хотя вроде заполнение происходит в асинхронном методе.
Почему форма виснет при заполнении прогрессбара?
вот код (FW 2.0):
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ProgressBar
{
public partial class Form1 : Form
{
private delegate void Async();

private void Progress()
{
pictureBox1.Invoke(new MethodInvoker(delegate { pictureBox1.Visible = true; }));
for (float i = 0; i < 30000; i++)
{
progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Value = (int)i; }));
}
pictureBox1.Invoke(new MethodInvoker(delegate { pictureBox1.Visible = false; }));
}

public Form1()
{
InitializeComponent();
}

private void btnEnter_Click(object sender, EventArgs e)
{
try
{
progressBar1.Value = Convert.ToInt32(textBox1.Text);
}
catch (Exception)
{
MessageBox.Show("При выполнении преобразования типов возникла ошибка");
return;
}
}

private void btnStart_Click(object sender, EventArgs e)
{
Async prdelegate = new Async(Progress);
AsyncCallback cb = new AsyncCallback(CallBackMethod);
prdelegate.BeginInvoke(cb, prdelegate);			
}

private void CallBackMethod(IAsyncResult ar)
{
Async prdelegate = (Async)ar.AsyncState;			
prdelegate.EndInvoke(ar);			
}
}
}
 
M

mms

Гость
#2
Специально для этого есть класс BackgroundWorker (для того, чтобы не париться с инвоками, потоками и делегатами :( ).

А вообще после строчки:

Код:
progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Value = (int)i; }));
надо написать:

Код:
Application.DoEvents();
Итого:

Код:
progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Value = (int)i; }));
Application.DoEvents();
 
E

EuGenius

Гость
#3
Для: sax_ol

Финт в том, что сразу использовалась флоатовская переменная и шаг был 0,2.
А progressBar1.Value принимает только интовские переменные. так и осталось. лень исправлять. это на скорость не влияет.

http://msdn2.microsoft.com/en-us/library/ms993020.aspx - а здесь я уже был. хотелось бы свое чудо докрутить до ума...
 
E

EuGenius

Гость
#4
Вот так все получается
Код:
private void Progress()
{
pictureBox1.Invoke(new MethodInvoker(delegate { pictureBox1.Visible = true; }));

for (int i = 0; i < 30000; i++)
{
if(i%1000 == 0) progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Value = i; }));
Application.DoEvents();
}
pictureBox1.Invoke(new MethodInvoker(delegate { pictureBox1.Visible = false; }));

}
Необязательно обращаться к форме и менять значение прогрессбара через каждое инкрементирование, ведь это же не критично для пользователя.