我有一个程序正在更新sqlserver中的表,我有一个表单,我想显示它的进度,进度条正在递增但是没有显示。我需要使用后台工作者吗?我正在做什么的例子
public void updateTable(string tableName)
{
// con is an instance of my form to access progressbar
con.progressBar1.Minimum = 1;
con.progressBar1.Step = 1;
string dbQuery = "select summet from someting"
con.progressBar1.Maximum = address.Tables[0].Rows.Count;
MessageBox.Show("progress bar max " + con.progressBar1.Maximum);
foreach (DataRow LonLat in address.Tables[0].Rows)
{
con.progressBar1.PerformStep();
MessageBox.Show(con.progressBar1.Value.ToString()); // this is incrementing
//plus updating table
}
}
答案 0 :(得分:2)
简短回答,是的。如果从主线程执行此操作,则不会看到进度条更新。
答案很长:
每当您将一段代码中的用户界面修改为“消息”进入窗口消息队列时,该队列将获取该消息并在主线程中相应地更新UI。
但是,由于主线程忙于处理您的代码,因此没有实际更新用户界面的“时间”,并且只有在您的过程完成后,才可以自由更新用户界面。这就是为什么你看到进度条从0%变为100%而没有任何中间步骤。
你应该做什么:
你想做的是把工作放到后台工作者,这样主线程可以自由地参加UI更新请求......顺便说一下,如果你想让UI保持响应,那就是标准做法。
答案 1 :(得分:0)
是的,你应该使用后台工作者,但它可能没有用,我们需要看到绑定和其他一切,使用后台工作者使用这样的东西:
Window.Dispatcher.BeginInvoke((Action)(() =>
{
con.progressBar1.PerformStep();
}
答案 2 :(得分:0)
是的,你必须使用后台工作者
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (o, ea) =>
{
// your code goes here
}
worker.RunWorkerCompleted += (q, ea) =>
{
}
worker.RunWorkerAsync();
答案 3 :(得分:0)
如果我们无法使用BackgroundWorker,就会发生这种情况。我有一个带有进度条的表单,其唯一的工作是接受一个命令到PerformStep,从打开它的其他表单,表单必须只是这样做。两种形式都在GUI线程中。 尽管如此,我从进度条中得不到一致的行为。在下面的代码中,进度条总是落后于其属性所表示的一步:
public partial class Form1 : Form
{
private readonly int m_numOfSteps;
public Form1(int numOfSteps)
{
m_numOfSteps = numOfSteps;
InitializeComponent();
}
private void Form1_Load( object sender, EventArgs e )
{
progressBar1.Step = (int)Math.Ceiling( 100.0 / m_numOfSteps );
}
public void DoStep(string msg)
{
progressBar1.PerformStep();
label1.Text = msg;
label2.Text = String.Format( "{0}%", progressBar1.Value );
label1.Refresh();
label2.Refresh();
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click( object sender, EventArgs e )
{
using( Form1 f = new Form1( 3 ) )
{
f.Show();
f.Refresh();
Thread.Sleep( 1000 );
f.DoStep( "AAAA" );
Thread.Sleep( 1000 );
f.DoStep( "BBBB" );
Thread.Sleep( 1000 );
f.DoStep( "CCCC" );
Thread.Sleep( 1000 );
}
}
}