后台工作程序允许UI在迭代Outlook MailItems时冻结

时间:2013-02-11 23:46:48

标签: c# wpf outlook backgroundworker mailitem

我正在开发一个WPF支持工具,它查看共享的Outlook邮箱,收集文件夹,在TabControl中创建TabItems来表示文件夹,然后收集它在过去14天的文件夹中找到的MailItems。每个文件夹可能只有大约十几个MailItems,因此在任何范围内都不是很大。

启动时,应用程序遍历每个文件夹的Mailitems,并将它们添加到MailItem列表中,稍后我将添加到相应TabItem的ListBox的绑定ObservableCollection。

我遇到的问题是UI在Outlook文件夹中的MailItems中进行迭代时会锁定。我添加了一个Backgroundworker例程,首先在后台收集邮件,但在此期间UI仍然完全没有响应。我不明白为什么这个过程根本不会弄乱UI。

我的简化代码如下。请注意,除了在此示例中迭代它们之外,我实际上对MailItems一无所知,但它冻结了UI。为什么?另外值得注意的是,总共有大约10个Outlook文件夹。创建一个TabItem(以ListBox作为内容)来表示文件夹,从而导致下面的代码启动 - 换句话说,在初始化过程中应该有大约10个Backgroundworkers启动。

有什么建议或想法可以更好地实现这一点吗?理想情况下,我希望应用程序启动并平滑地填充显示,而不是挂起并突然显示所有内容。

List<MailItem> mailList = new List<MailItem>();

        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(delegate
            {
                Items folderItems = folder.Items.Restrict(filter);

                foreach (MailItem mi in folderItems.OfType<MailItem>())
                {
                    // would normally add to mailList here. 
                }
            });
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate
            {
                 // then add to the ObservableCollection of the UI ListBox.
            });

        worker.RunWorkerAsync();
        worker.Dispose();

1 个答案:

答案 0 :(得分:-1)

我不确定这是否会导致您的UI锁定,但您不应该在Dispose之后BackgroundWorker上调用RunWorkerAsync,因为它会大致相同时间DoWorkRunWorkerCompleted之前。您可以在Dispose处理程序中调用RunWorkerCompleted(我更喜欢这样,因为它将所有内容保存在一个位置)或保存工作程序,并在以后放置包含类时执行此操作。