WPF多线程进度对话框 [英] WPF multithreaded progress dialog
问题描述
已更新这是一个有趣的问题。当后台进程运行时,我需要一个进度对话框显示。通常,这将工作,但问题是我需要在后台进程中设置公共静态数据。以下是我试图完成的一个例子:
Updated This is kind of an interesting problem I am experiencing. I need to have a progress dialog show when a background process is running. Normally, this would work but the problem is that I need to set public static data within the background process. Here is an example of what I am attempting to accomplish:
public partial class MainWindow : Window
{
public static Service binding;
public static Result lr;
public progressDialog dlg;
private void login()
{
string sPwd = txtPwd.Password;
string sEmail = txtEmail.Text;
binding = new Service();
lr = binding.login(sEmail, sPwd);
}
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker;
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted)
worker.RunWorkerAsync();
dlg = new progressDialog();
dlg.Show();
login();
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = login();
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Hid();
Window1 newWindow = new Window1();
newWindow.Show();
dlg.Close();
}
我知道这样做,因为login()是一个void和在DoWork事件中实际没有返回一个与e.Result一起使用的值。但是,我已经设置了一个登录类来传递参数,我仍然收到错误,指出我无法访问UI线程。主要的问题是lr和绑定被另一个窗口访问,所以它们必须是公共静态数据(从另一个窗口我设置public static Service binding = MainWindow.binding;)。
I know that as this stands, it will not work because login() is a void and does not actually return a value to use with e.Result in the DoWork event. However, I have set up a login class to pass the parameters to and I still receive errors stating that I cannot access the UI thread. The main problem is that lr and binding are accessed by another window so they must be public static data (from the other window I set public static Service binding = MainWindow.binding;). I'm just having a bit of trouble wrapping my head around how exactly to set this up.
推荐答案
你需要阅读前台线程上的TextBoxes(txtEmail和txtPwd),而不是后台线程。这里有一个例子:
You need to read from the TextBoxes (txtEmail and txtPwd) on the foreground thread, not the background thread. Here's an example:
class MainWindow
{
private string _email;
private string _password;
private void btnLogin_Click(...)
{
// running on UI thread here - can touch text boxes
_email = txtEmail.Text;
_password = txtPwd.Text;
// ... set up worker ...
worker.RunWorkerAsync();
}
private void login()
{
binding = new Service();
// running on background thread here
// but safe to access _email and _password they're just data, not UI controls
lr = binding.login(_email, _password);
}
}
编辑:更好,将电子邮件和密码作为参数传递,而不是将其存储在成员变量中:
Even better, pass the email and password as arguments rather than storing them in member variables:
private void btnLogin_Click(...)
{
// running on UI thread here - can touch text boxes
LoginInfo loginInfo = new LoginInfo(txtEmail.Text, txtPwd.Text);
// ... set up worker ...
worker.RunWorkerAsync(loginInfo); // note argument
}
private void worker_DoWork(...)
{
LoginInfo loginInfo = (LoginInfo)(e.Argument);
// now pass the LoginInfo to login() as an argument
}
(并删除_email和_password成员)
(and remove the _email and _password members)
这篇关于WPF多线程进度对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!