在另一个线程中运行进度条
我试图在单击按钮时显示进度条,并在工作完成时将其隐藏。但是当我在按钮事件处理程序中显示进度条时,它不起作用,并且仅在完成工作后才显示。在另一个线程中运行进度条
这里是我的代码:在WPF
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;
}
}
看一看后台工作(http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx)
它可以让你在一个单独的专用线程上运行操作。 在后台计算,可以提高ProgressChanged的事件,通知UI并相应更新进度:
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();
}
UI需要在UI线程上执行。并且您认识到,因为我可以使用Dispatcher.BeginInvoke
与您的进度窗口进行交互。
虽然你的问题是你也在UI线程上执行长时间运行的任务。当你这样做时,你不会让进度窗口有机会运作。线程被长时间运行的任务占用,因此无法为UI提供服务。
解决方案是从UI线程执行长时间运行的任务。
当我这样做,它得到错误,对象是自己对当前线程不能可以通过另一个线程访问。\ – 2013-03-07 09:14:08
然后使用代理从跨线程进行访问。 – James 2013-03-07 09:15:15
然后你需要解决这个问题。它不会改变您需要远离UI线程执行长时间运行的任务的事实。 – 2013-03-07 09:17:28
发生这种情况是因为您的UI线程正在完成所有工作(访问数据库),直到完成,它无法处理更多消息(如显示进度条)。
您需要做相反的事情,在没有BeginInvoke的UI线程中显示进度条,并在另一个线程中执行数据库访问。当其他线程完成时,您需要在UI线程上执行BeginInvoke来隐藏进度条。
这里是另一个重要的注意事项:this.Dispatcher.BeginInvoke不产生线程。它将命令“推入”UI线程的队列,因为所有UI操作必须从UI线程执行。
这里是你做什么:
私人无效Button_Click_1(对象发件人,RoutedEventArgs E)
- 显示进度条
- 使用任务将启动后台进程
- 添加后续任务到您的第一个任务发送消息到UI,该过程已完成
- 在继续任务中使用this.Dispatcher.BeginInvoke,以便UI人员发生在UI线程上。
谢谢你,它工作:) – 2013-03-08 07:11:28