[英]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.