C#鎖定語句一次只允許一個線程訪問對象。 在Parallel.ForEach循環中,在循環中創建新對象(局部變量)不是更快,而不是使用字段變量,因爲這樣就不會阻塞任何線程? 每種方式的優點/缺點是什麼?線程鎖定與創建新對象
我使用下面的代碼,似乎創建一個本地變量,而不是在字段上使用鎖定稍快。
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);
});
如果您的共享對象具有某種您關心的獨特狀態信息,那麼您不能僅僅創建新的狀態信息。 –
如果我記得正確TPL也支持其循環中的線程局部變量。 – Dirk
通常,通過創建一個線程池,可以在啓動時創建一個「重」,然後在池隊列中循環,爲「重」創建數據,從而避免不斷創建繁重的對象和線程。換句話說,我可能不會使用任何一種替代品。 –