Как реализовать словарь в многопоточном сценарии, чтобы избежать ArgumentNull Exception?

Я пытаюсь реализовать словарь в многопоточном сценарии. В одном потоке он работает нормально, однако в многопоточном сценарии я получил исключение 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 (получатель.Имя, выходное значение1), bcc.TryGetValue(получатель.Имя, выходное значение) и to.TryGetValue(получатель.Name, выходное значение2)

{System.ArgumentNullException: значение не может быть нулевым. Имя параметра: ключ в System.ThrowHelper.ThrowArgumentNullException(аргумент ExceptionArgument) в System.Collections.Generic.Dictionary2.FindEntry(TKey key) at System.Collections.Generic.Dictionary2.TryGetValue (ключ TKey, TValue& значение) в ABC.Common.Collection.SynchronizedDictionary`2.TryGetValue(ключ TKey, TValue& значение) в (Путь к файлу класса)

2 ответа

Проблема, вероятно, исходит от:

finally
{
    NAR(recipient);
}

Вы не должны освобождать COM-объекты во время обработки, потому что они могут быть общими и использоваться другими потоками, работающими с другими письмами.

Отпустите их, только когда все потоки закончили обрабатывать почту.

Вы можете отслеживать их в списке, например, и в конце выпустить их в одной партии.

Я нашел решение, используя [MethodImpl(MethodImplOptions.Synchronized)] над именем метода, но это делает медленнее.

Возможно ли это с другими альтернативами?

Спасибо Бинод

Другие вопросы по тегам