从Outlook(interop)检索单个项目的最有效方法是什么

时间:2012-06-13 12:40:34

标签: c# interop outlook

我需要创建一个程序,将自己的任务对象与outlook中的任务同步。在操作期间,可以创建/更新/删除outlook中的任务。

最直接的方法是迭代outlook中的所有任务项,寻找要更新的任务。非常粗略:

ApplicationClass _app;
NameSpace _nameSpace;
MAPIFolder _folder;

_app = new ApplicationClass();
_nameSpace = _app.GetNamespace("MAPI");
_folder = _nameSpace.GetDefaultFolder(OlDefaultFolders.olFolderTasks);

Dictionary<int,MyTask> data = GetData();

for (int i = 1; i <= _folder.Items.Count; i++)
{
    TaskItem taskItem = (TaskItem)_folder.Items.Item(i);
    int itemID;
    if(ItemNeedsProcessing(taskItem, out itemID))
        UpdateItem(taskItem, data[itemID]);
}

但这可能会遍历数百个项目(取决于客户端的Outlook任务历史记录),只是进行一两次更改。

或者,我可以跟踪任务的ItemID ...

string itemID = "00000000873..."; //taken from property on object.
object o = _nameSpace.GetItemFromID(itemID); //ignore possible exceptions for now
TaskItem taskItem = (TaskItem)o;

...并直接更新(使应用程序端的任务创建/删除变得复杂)。

直接检索任务项(GetItemFromID)是最有效的方法吗?或者是否有一些陷阱我错过了?

2 个答案:

答案 0 :(得分:4)

Outlook 2007+添加了Folder.GetTable,与Folder.Items相比,它使用轻量级方法优化了检索。使用表格 can be up to 10x faster而非项目迭代器。

至于检索实际项目,Session.GetItemFromID是检索项目的最快方法 - 特别是如果您将Store.StoreID作为辅助参数传递,那么Outlook不必确定哪个商店特定EntryID所属。

const string PR_STORE_ENTRYID = "http://schemas.microsoft.com/mapi/proptag/0x0FFB0102";
Outlook.Table tasks = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderTasks).GetTable();
tasks.Columns.Add(PR_STORE_ENTRYID); // optimal for GetItemFromID
while (!tasks.EndOfTable)
{
    Outlook.Row task = tasks.GetNextRow();
    Outlook.TaskItem item = Application.Session.GetItemFromID(task["EntryID"], task.BinaryToString(PR_STORE_ENTRYID)) as Outlook.TaskItem;
} 

至于最佳方法 - 如果您希望最小化同步执行时间,则应跟踪应用程序中的任务EntryID 任务StoreID 。否则,检索所有任务的强力方法会有效,但我建议使用Folder.GetTable()而不是Folder.Items

答案 1 :(得分:1)

在SliverNinja的answer上构建,我的建议是使用Outlook赎回RDO Library。它是第三方商业工具,但它允许您在Outlook 2003(及更高版本)中使用MAPITable