我的加载项是使用面向Outlook 2007的Visual Studio 2010.加载项的一项任务是将所有邮件项目从文件夹移动到指定的文件夹。
我的第一阶段测试只是修改了主题并将电子邮件保存在同一个文件夹中。没有问题。
当我从.Save方法更改为使用.Move方法时,我无法处理所有项目。有些人会被移动,然后 foreach 循环过早退出而不会抛出任何异常。
我的测试数据在我看来非常受控制,因为我在使用调试器逐步执行代码之前手动将项目移动到我想要处理的文件夹中。例如,在文件夹中有4个mailitems,我可以移动其中的2个,当重新访问 foreach 时,它会退出循环,留下2个mailitems未经处理。
有什么想法吗?
if (ProcessFolder(theRootFolder.FolderPath) && (theRootFolder.Items.Count > 0))
{
int itemCount = theRootFolder.Items.Count;
int loopCount = 0;
MetaDataForm getMetaData = new MetaDataForm(theRootFolder.FolderPath, theRootFolder.Items.Count);
getMetaData.ShowDialog();
if (getMetaData.DialogResult == DialogResult.OK)
{
string d1 = getMetaData.Meta1;
string d2 = getMetaData.Meta2;
try
{
foreach (Object item in theRootFolder.Items)
{
loopCount++;
Outlook.MailItem mi = item as Outlook.MailItem;
if (mi != null)
{
mi.Move(_TRIM_archiveFolder);
}
}
}
catch (Exception ex)
{
ex.ToString();
MessageBox.Show(String.Format("ItemCount={0},LoopCount={1},ExceptionData={2}",
itemCount, loopCount, ex));
}
MessageBox.Show(String.Format("ItemCount={0},LoopCount={1}",
itemCount, loopCount));
}
}
编辑:
好主意....向后循环解决了问题:
// iterating backwards is needs because of .move below
for (int i = theRootFolder.Items.Count; i > 0; i--)
{
Outlook.MailItem mi = (Outlook.MailItem)theRootFolder.Items[i];
if (mi != null)
{
if (!mi.Subject.StartsWith("M1"))
{
mi.Move(_TRIM_archiveFolder);
}
}
}
答案 0 :(得分:3)
通常在使用foreach
时,当迭代的集合发生更改时,运行时不会太喜欢它。
我在这里做了一个疯狂的猜测,但我认为你可以从你的4个项目中移出2个的原因是,当你进入第三次迭代时,剩下的两个项目已移动到{{1}收集,现在位于第0和第1位,而你正在看第2位。
使用带有Items.Count()>的for循环或while循环。 0或类似的东西。
我也猜测你实际上在发生这种情况时会遇到异常,但它永远不会突然出现在你面前。尝试在WinDbg中附加该过程,看看发生了什么。您可能正在获得某种COM错误。
Outlook API几乎不是所有的COM库吗?
编辑:
你的想法是对的。给我一个向后迭代的想法:
Items