关于C#:WPF中的并行进程

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();
}

}


不要关闭Execute方法中的ProgressWindow,因为它在后台线程上运行,不应该在UI线程上操作对象。在BackgroundWorkerRunWorkerCompleted委托中关闭它,该委托在任务完成后在UI线程上执行。


首先,在initializecomponents方法中调用showdialog将阻塞UI,并且不是很好的解决方案;不会将任何事件转发到GUI线程,这就是为什么它永远不会关闭的原因。子窗体的close()方法必须在任务完成时调用自己的close;