parallel process in wpf
下面是我的场景:我有一个主窗口。在打开父窗口之前,我想打开一个ProgressWindow并从显示此窗口的数据库中获取数据。数据获取完成后,我希望使用委托关闭ProgressWindow,并且遇到线程问题。只是想知道你是否有什么建议:
以下是ParentWindow的代码:
使用系统;
使用system.collections.generic;
使用system.linq;
使用system.text;
使用system.windows;
使用system.windows.controls;
使用system.windows.data;
使用system.windows.documents;
使用system.windows.input;
使用system.windows.media;
使用system.windows.media.imaging;
使用system.windows.shapes;
命名空间RounderProgressBar{
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /// <summary> /// Interaction logic for Window2.xaml /// </summary> public partial class ParentWindow : Window { public ParentWindow() { InitializeComponent(); progress = new ProgressWindow(); progress.publisher = this.Subscriber; progress.ShowDialog(); } ProgressWindow progress;// = new Window1(); protected EventHandlerWithParms _subscriber; protected EventHandlerWithParms Subscriber { get { if (_subscriber == null) { _subscriber = new EventHandlerWithParms(Execute); } return _subscriber; } } private void Execute(object sender, EventArgs e) { (sender as Window).Close();//.Dispatcher.Invoke(Subscriber,null);//.InvokeShutdown();//.Close(); //progress.Close(); //this.Close(); //Window w = new Window(); //w.ShowDialog(); } } |
}
下面是子窗口或进程窗口:
1 | using System; |
使用system.collections.generic;
使用system.linq;
使用system.text;
使用system.windows;
使用system.windows.controls;
使用system.windows.data;
使用system.windows.documents;
使用system.windows.input;
使用system.windows.media;
使用system.windows.media.imaging;
使用system.windows.navigation;
使用system.windows.shapes;
使用system.componentmodel;
使用system.collections;
命名空间RounderProgressBar{
1 2 3 | /// <summary> /// Interaction logic for Window1.xaml /// </summary> |
公共分部类ProgressWindow:窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | { public ProgressWindow() { InitializeComponent(); StartWorker(null, null); } private BackgroundWorker _worker; private void StartWorker(object sender, RoutedEventArgs e) { _worker = new BackgroundWorker(); _worker.WorkerReportsProgress = true; _worker.WorkerSupportsCancellation = true; _worker.DoWork += delegate(object s, DoWorkEventArgs args) { BackgroundWorker worker = s as BackgroundWorker; //for (int i = 0; i < 10; i++) //{ if (worker.CancellationPending) { args.Cancel = true; return; } //System.Threading.Thread.Sleep(1000); runInBack(); //int max = int.Parse((_progressBar.Maximum - 1).ToString()); //If we comment this it will go into infinite loop as completed will never get triggered //worker.ReportProgress(/*max*/9);//worker.ReportProgress(9);//worker.ReportProgress(i + 1); worker.ReportProgress(9); //} }; _worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args) { //_progressBar.Value = args.ProgressPercentage; }; _worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args) { //_btnStart.IsEnabled = true; //_btnCancel.IsEnabled = false; //_progressBar.Value = 0; }; _worker.RunWorkerAsync(); //_btnStart.IsEnabled = false; //_btnCancel.IsEnabled = true; } private void runInBack() { System.Threading.Thread.Sleep(3000); //IsBusExecuted = true; if (this.publisher != null) publisher(this, null); } public EventHandlerWithParms publisher; private void CancelWorker(object sender, RoutedEventArgs e) { _worker.CancelAsync(); } private bool IsBusExecuted = false; void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (IsBusExecuted) { t.Stop(); MessageBox.Show("1"); this.rpb.Stop(); } } private void Execute(object sender, EventArgs e) { this.Close(); } private System.Timers.Timer t = new System.Timers.Timer(1000); } public delegate void EventHandlerWithParms(object sender, EventArgsWithParms e); public class EventArgsWithParms : EventArgs { public EventArgsWithParms() { } public Hashtable ParmTable = new Hashtable(); } |
}
不要关闭
首先,在initializecomponents方法中调用showdialog将阻塞UI,并且不是很好的解决方案;不会将任何事件转发到GUI线程,这就是为什么它永远不会关闭的原因。子窗体的close()方法必须在任务完成时调用自己的close;