多线程场景下使用Redemption GetMessageFromID

Using Redemption GetMessageFromID in multithreaded scenario

我已经阅读了关于从多个线程使用赎回的常见问题解答,但我不清楚 "creatable Redemption object" 是什么? 我们正在使用 Redemption 从已发送的项目中获取正确的发送日期和 Internet 消息 ID。 我从主线程初始化一个全局对象并从主线程设置 MAPISESSION,这样:

public void Init()
{
    _rdoSession.Logon();
    _rdoSession.MAPIOBJECT = ThisAddIn.Instance.Session.MAPIOBJECT;

    _storeId = ThisAddIn.Instance.Session.DefaultStore.StoreID;
}

然后我通过这种方式获取物品:

public RDOMail GetEmailFromServer(string entryID, string storeID = null)
{
    try
    {
        if (storeID == null)
        {
            storeID = _storeId;
        }
        return _rdoSession.GetMessageFromID(entryID, storeID, MAPI_NO_CACHE | MAPI_BEST_ACCESS);
    }
    catch (Exception e)
    {
        Log.Error(e, "Error getting message from server with RDO");
    }

    return null;
}

public Task<RDOMail> GetEmailFromServerAsync(string entryID, string storeID = null)
{
    return Task.Run(() => GetEmailFromServer(entryID, storeID));
}

似乎可以,但是在这种情况下它使用共享会话吗? 据我了解,RDOMail 是一个 COM 对象,它被传递到另一个线程(并在那里用 Marshal.ReleaseComObject 清除)。这样可以吗,还是我们最好在我们得到它的线程中完成所有事情?

也许有更简单的方法从服务器获取 Internet 消息 ID 和发送日期?它是否在我们的实施中下载了整个电子邮件(带附件)?

首先,没有理由调用Logon设置MAPIOBJECT属性。只需正确设置 MAPIOBJECT。

其次,由于您的代码是 运行 在 COM 插件中,因此无需创建全局 RDOSession(除非您确实在使用它)- Outlook 会为您初始化 MAPI 系统无论如何在主线程上。

第三,单独线程 (Task.Run) 中的代码 运行 需要它自己的 RDOSession 才能在该线程上初始化 MAPI。为此,您需要将 ThisAddIn.Instance.Session.MAPIOBJECT 存储在主线程上调用的 Init() 方法中的单独变量中。单独线程中的代码 运行 然后需要创建自己的 RDOSession 并将 MAPIOBJECT 属性 设置为主线程上设置的变量 - 这样你就不会在线程之间编组任何 OOM 对象(Outlook 真的不喜欢)。