1

我正在尝试在多线程场景中实现字典。在单线程中它工作正常但是在多线程场景中我得到了 ArgumentNull 异常。我试过使用锁仍然没有运气。下面是我的实现的代码细节。

这里 IRDOMail oItem 是来自 Exchangeserver WebService 的类。

var bcc = new Dictionary<string, bool>(7, StringComparer.InvariantCultureIgnoreCase);
var cc = new Dictionary<string, bool>(7, StringComparer.InvariantCultureIgnoreCase);
var to = new Dictionary<string, bool>(7, StringComparer.InvariantCultureIgnoreCase);

                    if (oItem.BCC != null)
                    {
                        foreach (var itemBcc in oItem.BCC.Split(';'))
                            if (!string.IsNullOrEmpty(itemBcc.Trim()))
                            {
                                lock (bcc)
                                    bcc[itemBcc.Trim()] = true;
                            }
                    }
                    if (oItem.CC != null)
                    {
                        foreach (var itemCc in oItem.CC.Split(';'))
                            if (!string.IsNullOrEmpty(itemCc.Trim()))
                            {
                                lock (cc)
                                    cc[itemCc.Trim()] = true;
                            }
                    }
                    if (oItem.To != null)
                    {
                        foreach (var itemTo in oItem.To.Split(';'))
                            if (!string.IsNullOrEmpty(itemTo.Trim()))
                            {
                                lock(to)
                                    to[itemTo.Trim()] = true;
                            }
                    }

                    var bccEntries = new List<string>(bcc.Count);
                    var ccEntries = new List<string>(cc.Count);
                    var toEntries = new List<string>(to.Count);

                    RDORecipients recipients = null;
                    RDORecipient recipient = null;
                    try
                    {
                        recipients = oItem.Recipients;
                        for (int i = 1; i <= recipients.Count; i++ )
                        {
                            try
                            {
                                recipient = recipients[i];
                                if (recipient == null || recipient.EntryID == null)
                                    continue;
                                if (string.IsNullOrEmpty(recipient.Name))
                                    continue;
                                lock (bcc)
                                {
                                    bool value;
                                    if (bcc.TryGetValue(recipient.Name,out value))
                                        bccEntries.Add(recipient.EntryID);
                                }
                                lock (cc)
                                {
                                    bool value1;
                                    if (cc.TryGetValue(recipient.Name, out value1))
                                        ccEntries.Add(recipient.EntryID);
                                }
                                lock (to)
                                {
                                    bool value2;
                                    if (to.TryGetValue(recipient.Name, out value2))
                                        toEntries.Add(recipient.EntryID);
                                }
                            }
                            finally
                            {
                                NAR(recipient);
                            }
                        }
                    }
                    finally
                    {
                        NAR(recipients);
                        recipients = null;
                    }

例外: -

这些异常在尝试获取值时发生,即 cc.TryGetValue(recipient.Name, out value1)、bcc.TryGetValue(recipient.Name,out value) 和 to.TryGetValue(recipient.Name, out value2)

{System.ArgumentNullException:值不能为空。参数名称: System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) at System.Collections.Generic.Dictionary 2.FindEntry(TKey key) at System.Collections.Generic.Dictionary2.TryGetValue(TKey key, TValue& value) at ABC.Common.Collection.SynchronizedDictionary`2.TryGetValue(TKey key, TValue& value) ) 在(类文件路径)

4

2 回答 2

1

问题大概来自:

finally
{
    NAR(recipient);
}

您不应在处理期间释放 COM 对象,因为它们可能会被处理其他邮件的其他线程共享和使用。

仅当所有线程完成处理邮件时才释放它们。

例如,您可以在列表中跟踪它们,最后将它们分批发布。

于 2013-11-11T11:12:56.913 回答
0

我在方法名称上方使用 [MethodImpl(MethodImplOptions.Synchronized)] 找到了解决方案,但这会变慢。

是否有可能与其他替代品一起使用?

谢谢比诺德

于 2013-11-11T12:20:14.817 回答