parallel process in wpf
Here is my scenario: I have a Main ParentWindow . Before opening the parent i would like to open a progressWindow and fetch the data from DB displaying this window. After the data fetch is complete i would like to close the progressWindow by using a delegate and i am running into threading issues. Just wondering if you have any suggestions:
Here is the code for ParentWindow:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace RounderProgressBar {
/// <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).Clos开发者_JS百科e();//.Dispatcher.Invoke(Subscriber,null);//.InvokeShutdown();//.Close();
//progress.Close();
//this.Close();
//Window w = new Window();
//w.ShowDialog();
}
}
}
Here is the child or progressWindow:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections;
namespace RounderProgressBar {
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class ProgressWindow : Window
{
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();
}
}
First of all, calling ShowDialog in InitiallizeComponents method will block UI and not very good solution; No events will be forwarded to GUI thread and that's why it will never close. Close() method of child form must call its own close when tasks are finished;
Don't close the ProgressWindow
in the Execute
method, because that's running on the background thread and shouldn't manipulate objects on the UI thread. Close it in the BackgroundWorker
's RunWorkerCompleted
delegate, which executes on the UI thread once the task is finished.
精彩评论