在多线程方案中使用Redemption GetMessageFromID

时间:2018-08-10 08:40:36

标签: multithreading outlook outlook-redemption

我已阅读有关在多个线程中使用赎回的常见问题解答,但是我不清楚什么是“可创建的赎回对象”? 我们正在使用兑换来从已发送邮件中获取正确的发送日期和互联网消息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和发送日期?是否在我们的实施中下载整个电子邮件(带有附件)?

1 个答案:

答案 0 :(得分:1)

首先,没有理由调用#!/usr/bin/env python from __future__ import print_function import os from selenium import webdriver def main(): driver = webdriver.Chrome() # With automatically closes files when they go out of scope with open('test.txt', 'r') as f: for url in f.readlines(): driver.get(url) # os.path.join should make it platform agnostic # Also remove any '/' from the url and replace to avoid any file system save issues sn_name = os.path.join('Screenshots', url.strip().replace('/', '-') + '.png') print('Attempting to save:', sn_name) # '.save_screenshot' returns false if it fails so throw exception if not driver.save_screenshot(sn_name): raise Exception('Could not save screen shot: ' + sn_name) # Close browser driver.quit() if __name__ == '__main__': main() 并设置Logon属性。只需正确设置MAPIOBJECT。

第二,由于您的代码在COM加载项中运行,因此无需创建全局MAPIOBJECT(除非您确实在使用它)-无论如何,Outlook都会在主线程上为您初始化MAPI系统。

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