线程和对象通过引用

时间:2012-03-08 07:36:25

标签: c# thread-safety

我想问一下这段代码是否安全? attachment对象存在问题。它通过引用传递给MailHelper使用它的新线程,有时在线程之间混合attachment对象。

public static void Start() 
{
    foreach (var message in messages)
    {
        //skip code
        var fileName = httpWebResponse.GetResponseHeader("filename");
        var fileStream = httpWebResponse.GetResponseStream();
        var attachment = new Attachment(fileStream, fileName);

        var thread = new Thread(() =>
        {
            var dictionary = new ListDictionary
            {
                { "$Url$", message.Url }
            };

            MailHelper.SendMessage(dictionary,
                message.Mail.Headers.From.Address, 
                "EmailConvertSuccess.txt",
                attachment)
        });

        thread.Start();
    }
}

2 个答案:

答案 0 :(得分:1)

不,这可能不会起作用 - 但它不仅是附件(参见Darins的答案),还有你用作迭代器的message对象 - 你必须在调用之前将它复制到本地实例你的线程是这样的:

var messageCopy = message;
new Thread(a =>
        MailHelper.SendMessage(
            new ListDictionary { { "$Url$", messageCopy .Url } },
            messageCopy.Mail.Headers.From.Address, 
            "EmailConvertSuccess.txt",
            a as MailAttachment)
    ).Start(attachment);

如果你真的想要,你可以将其作为参数传递 - 就像Darin用它的变体做的那样,但我不认为这是真的需要)

答案 1 :(得分:1)

我认为attachment没有问题。是的,它是在一个闭包中捕获的,但是当它在循环内声明时,应该没有任何问题。

但是,message存在问题。尝试var message1 = message;,然后在lambda中使用message1