Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何在多线程场景中实现字典以避免ArgumentNull异常?_Multithreading_Dictionary_Argumentnullexception - Fatal编程技术网

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

Multithreading 如何在多线程场景中实现字典以避免ArgumentNull异常?,multithreading,dictionary,argumentnullexception,Multithreading,Dictionary,Argumentnullexception,我试图在多线程场景中实现字典。 在单线程中,它可以正常工作,但是在多线程场景中,我得到了ArgumentNull异常。 我试过用这把锁,但还是不走运。 下面是我的实现的代码细节 这里的IRDOMail oItem是来自Exchangeserver Web服务的类。 var bcc = new Dictionary<string, bool>(7, StringComparer.InvariantCultureIgnoreCase); var cc = new Dictionary&l

我试图在多线程场景中实现字典。 在单线程中,它可以正常工作,但是在多线程场景中,我得到了ArgumentNull异常。 我试过用这把锁,但还是不走运。 下面是我的实现的代码细节

这里的IRDOMail oItem是来自Exchangeserver Web服务的类。

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;
                    }
var bcc=新字典(7,StringComparer.InvariantCultureInogoreCase);
var cc=新字典(7,StringComparer.InvariantCultureInogoreCase);
var to=新字典(7,StringComparer.InvariantCultureInogoreCase);
如果(oItem.BCC!=null)
{
foreach(oItem.BCC.Split(“;”)中的var itemBcc)
如果(!string.IsNullOrEmpty(itemBcc.Trim()))
{
锁(密件抄送)
bcc[itemBcc.Trim()]=true;
}
}
如果(oItem.CC!=null)
{
foreach(oItem.CC.Split(“;”)中的var itemCc)
如果(!string.IsNullOrEmpty(itemc.Trim()))
{
锁(cc)
cc[itemc.Trim()]=true;
}
}
如果(oItem.To!=null)
{
foreach(oItem.To.Split(“;”)中的变量itemTo)
如果(!string.IsNullOrEmpty(itemTo.Trim()))
{
锁(到)
to[itemTo.Trim()]=true;
}
}
var bccEntries=新列表(bcc.Count);
var cEntries=新列表(抄送计数);
var toEntries=新列表(到.Count);
RDORecipients recipients=null;
RDORecipient recipient=null;
尝试
{
收件人=oItem.收件人;

对于(int i=1;i而言,问题可能来自:

finally
{
    NAR(recipient);
}
您不应该在处理过程中释放COM对象,因为它们可能会被处理其他邮件的其他线程共享和使用

只有当所有线程都处理完邮件后才释放它们


例如,您可以在列表中跟踪它们,并在最后以单个批次发布它们。

问题可能来自:

finally
{
    NAR(recipient);
}
您不应该在处理过程中释放COM对象,因为它们可能会被处理其他邮件的其他线程共享和使用

只有当所有线程都处理完邮件后才释放它们


例如,您可以在列表中跟踪它们,并在最后以单个批次发布它们。

我使用方法名称上方的[MethodImpl(MethodImplOptions.Synchronized)]找到了解决方案,但这会降低速度

有没有其他选择

谢谢
Beenodeh

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

有没有其他选择

谢谢
beenodeh

这不是一个解决方案,因为它完全取消了多线程的使用。
Synchronized
与Java中的语义相同:它指示CLR同步对该方法的所有访问,因此一次只能运行一个线程。将recipient.Name分配给某个变量,作为recipientName=recipient.Name并将其用作低于.if(bcc.TryGetValue(recipientName,out值))bcc和to也遵循同样的方法。这不是一个解决方案,因为它完全取消了多线程的使用。
Synchronized
具有与Java中相同的语义:它指示CLR同步对该方法的所有访问,因此一次只能有一个线程运行它。将recipientName作为recipientName=recipie将recipientName分配给某个变量按如下方式命名和使用它。如果(bcc.TryGetValue(recipientName,out value)),请遵循相同的bcc和to。