gpt4 book ai didi

c# - 在同步块(synchronized block)内部和外部使用字段是否安全?

转载 作者:太空狗 更新时间:2023-10-29 18:24:47 24 4
gpt4 key购买 nike

背景

我们的应用程序发送在数据库表中排队的电子邮件。我们遇到过一些重复发送电子邮件的情况,因此我实现了锁定以防止多个线程同时发送电子邮件。

ReSharper 警告我:

the field is sometimes used inside synchronized block and sometimes used without synchronization

问题

为什么 ReSharper 告诉我这个,我为什么要担心它?

代码

这是我的(删节的)代码:

private readonly IMailQueueRepository _mailQueueRepository = new MailQueueRepository();
private static object _messageQueueLock = new object();

public void SendAllQueuedMessages(IPrincipal caller)
{
lock (_messageQueueLock) // Prevent concurrent callers
{
var message = _mailQueueRepository.GetUnsentMessage();
while (message != null)
{
SendQueuedMessage(message);
message = _mailQueueRepository.GetUnsentMessage();
}
}
}

public void SendQueuedMessage(IMessage message)
{
// I get the ReSharper warning here on _mailQueueRepository
var messageAttachments = _mailQueueRepository.GetMessageAttachments(message.Id);
// etc.
}

最佳答案

问题场景:

We've had some instances of duplicate emails being sent, so I'm implementing a lock to prevent multiple threads from sending emails simultaneously.

因此您正在使用 Lock() 来防止这种情况发生,这意味着您需要同步访问公共(public)资源的线程,在本例中为 _mailQueueRepository

但是在相同的代码中,您再次使用没有 Lock_mailQueueRepository

 // I get the ReSharper warning here on _mailQueueRepository
var messageAttachments = _mailQueueRepository.GetMessageAttachments(message.Id); // <== Accessed without a lock

因此,这是一个警告,告诉您宝贵的资源以两种不同的形式被访问:一种是同步(线程安全),另一种是非同步(非线程安全).

这是一个警告,让 知道(或让您识别)可能因资源 _mailQueueRepository 的这种矛盾使用而引起的问题.您可以选择使用 _mailQueueRepository synchronized(使用 lock 并且警告将消失)或设法不参加比赛情况。

此外,您可能会考虑以这样一种方式重新构建代码,即使用从 _mailQueueRepository 中提取的参数调用您的 SendQueuedMessage() 避免混合使用。

关于c# - 在同步块(synchronized block)内部和外部使用字段是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28715625/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com