我正在尝试在多线程场景中实现字典。 在单线程中它工作正常但是在多线程场景中我得到了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)
答案 0 :(得分:1)
问题可能来自:
finally
{
NAR(recipient);
}
您不应在处理期间释放COM对象,因为它们可能被其他线程上的其他线程共享和使用。
只有当所有线程都已完成处理邮件时才释放它们。
例如,您可以在列表中跟踪它们,最后将它们一次性发布。
答案 1 :(得分:0)
我在方法名称上面找到了使用[MethodImpl(MethodImplOptions.Synchronized)]的解决方案,但这会变慢。
是否可以使用其他替代方案?
由于 Beenodh