[英]Thread locking vs creating a new object
C#lock语句一次仅允许一个线程访问一个对象。 在Parallel.ForEach循环中,在循环中创建一个新的对象(局部变量)比使用字段变量要快,因为那样就不会阻塞线程吗? 每种方式的利弊是什么?
我正在使用下面的代码,似乎创建本地var而不是在字段上使用锁稍微快一些。
nb。 toEmails变量中有3个电子邮件字符串。
//Method 1 with lock statement takes 14092ms
List<string> toEmails = getListOfToEmails();
Object locker = new object();
SmtpClient smtpClient = getSmtpObject();//smtpClient is used here as a field
Parallel.ForEach(toEmails, toEmail =>
{
string emailBody = getEmailBody(toEmail);
MailMessage mailMessage = getMailMesssageObject(emailBody, toEmail);
lock (locker)
{
smtpClient.Send(mailMessage);
}
});
//Method 2 without lock statement (creating a new local var each iteration) takes 13947ms
List<string> toEmails = getListOfToEmails();
Parallel.ForEach(toEmails, toEmail =>
{
SmtpClient smtpClient = getSmtpObject();//smtpClient is used here as a local var
string emailBody = getEmailBody(toEmail);
MailMessage mailMessage = getMailMesssageObject(emailBody, toEmail);
smtpClient.Send(mailMessage);
});
使用此ForEach
重载:
Parallel.ForEach(toEmails, () => getSmtpObject() , (toEmail, state, smtp) =>
{
SmtpClient smtpClient = smtp;
string emailBody = getEmailBody(toEmail);
MailMessage mailMessage = getMailMesssageObject(emailBody, toEmail);
smtpClient.Send(mailMessage);
return smtp;
}, smtp => {});
第二个参数是一个委托,您可以使用它来创建线程本地数据。 在循环的每个迭代中,您将获取本地数据,您可以对其进行更改并返回到下一个迭代。
最后一个参数是另一个委托,它将在每个任务结束时调用
如果存在共享资源,则在“简单锁定”中更可取。 正如您的情况一样,将SMTP CLIENT用作共享资源非常简单。 因此,如果您每次创建新对象,它都是非常安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.