如何在多线程场景中实现Dictionary以避免ArgumentNull异常?

时间:2013-11-11 10:37:48

标签: multithreading dictionary argumentnullexception

我正在尝试在多线程场景中实现字典。 在单线程中它工作正常但是在多线程场景中我得到了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:Value不能为null。 参数名称:key    在System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument参数)    在System.Collections.Generic.Dictionary 2.FindEntry(TKey key) at System.Collections.Generic.Dictionary 2.TryGetValue(TKey键,TValue&amp; value)    at(Class File Path)中的ABC.Common.Collection.SynchronizedDictionary`2.TryGetValue(TKey键,TValue&amp; value)

2 个答案:

答案 0 :(得分:1)

问题可能来自:

finally
{
    NAR(recipient);
}

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

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

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

答案 1 :(得分:0)

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

是否可以使用其他替代方案?

由于 Beenodh