我正在尝试在单击按钮时显示进度条,并在工作完成时隐藏它。但是当我在按钮事件处理程序中显示进度条时,它不起作用,仅在完成工作后显示。
这是我的代码:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
loadingprgoress.Visibility = Visibility.Visible;
}));
int usresult, psresult;
con.Open();
SqlDataReader data = null;
String myQueryEdit1 = @"SELECT Username, Password FROM [dbo].[Table]";
com.CommandText = myQueryEdit1;
com.Connection = con;
data = com.ExecuteReader();
Random rnd = new Random();
int newrnd = rnd.Next(1, 100);
if (data.Read())
{
string userhash = GenerateHashWithSalt(data["Username"].ToString(), newrnd.ToString());
string passhash = GenerateHashWithSalt(data["Password"].ToString(), newrnd.ToString());
string userhash1 = GenerateHashWithSalt("admin", newrnd.ToString());
string passhash1 = GenerateHashWithSalt(pasbox.Password, newrnd.ToString());
usresult = userhash.CompareTo(userhash1);
psresult = passhash.ToString().CompareTo(passhash1);
if (usresult == 0 && psresult == 0)
{
con.Close();
dental_main_Window neww = new dental_main_Window();
neww.Show();
Close();
}
else
{
con.Close();
pasbox.Password = "";
}
Thread.Sleep(3000);
this.Dispatcher.BeginInvoke((Action)(() =>
{
loadingprgoress.Visibility = Visibility.Hidden;
}));
return;
}
}
答案 0 :(得分:1)
这是因为您的UI线程正在完成所有工作(访问数据库),直到完成,它无法再处理任何消息(如显示进度条)。
您需要执行相反的操作,在没有BeginInvoke的UI线程中显示进度条,并在另一个线程中执行数据库访问。当其他线程完成时,您需要在UI线程上执行BeginInvoke以隐藏进度条。
这是另一个重要的注释:this.Dispatcher.BeginInvoke不会产生一个线程。它将命令“推送”到UI线程的队列,因为必须从UI线程执行所有UI操作。
以下是您的工作:
private void Button_Click_1(object sender,RoutedEventArgs e)
答案 1 :(得分:0)
WPF中的UI需要在UI线程上执行。并且您认识到这一点,因为我可以看到您使用Dispatcher.BeginInvoke
与进度窗口进行交互。
您的问题是您在UI线程上也执行长时间运行的任务。当您这样做时,您不会给进度窗口提供操作的机会。该线程由长时间运行的任务使用,因此无法为UI提供服务。
解决方案是远离UI线程执行长时间运行的任务。
答案 2 :(得分:0)
查看后台工作人员(http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx)
它允许您在单独的专用线程上运行操作。 在后台计算期间,您可以引发 ProgressChanged 事件以通知UI并相应地更新ProgressBar:
private BackgroundWorker _worker;
public Form1(string[] args)
{
InitializeComponent();
_worker = new BackgroundWorker();
_worker.WorkerReportsProgress = true;
_worker.RunWorkerCompleted += worker_WorkCompleted;
_worker.DoWork += worker_DoWork;
_worker.ProgressChanged += worker_ProgressChanged;
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
DoStuff();
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void worker_WorkCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_running = false;
UpdateUi();
}
private bool DoStuff()
{
//...
_worker.ReportProgress(20);
//...
_worker.ReportProgress(20);
return true;
}
private void btnUpdate_Click(object sender, EventArgs e)
{
_worker.RunWorkerAsync();
}