简体   繁体   中英

Thread locking vs creating a new object

The C# lock statement allows only one thread to access an object at a time. In a Parallel.ForEach loop, wouldn't it be faster to create a new object (local variable) within the loop, rather than using a field variable, since that way no threads are ever blocked? What would be the pros/cons of each way?

I am using the code below, it seems that creating a local var instead of using a lock on a field is slightly faster.

nb. There are 3 email strings in the toEmails variable.

//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);
});

Use this overload of 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 => {});

Second argument is a delegate that you can use it to create thread local data. in each iteration of loop you will get local data and you can change it and return to next iteration.

Last argument is another delegate this will be called in end of every task

In Simple lock is preferable when there is a shared resource. As in your case its quite simple that SMTP CLIENT is not used as a shared resource. so its quite safe if you create new object each time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM