[英]ASP.NET HostedService thread safe singleton
当读/写单例中使用的List
项目时,我是否需要关心线程安全。
如果是这样,我是否需要锁定Foo.Value
或FooManager.FooList
的getter/setter?
我知道读取项目并将其添加到List
不是线程安全的,但我不确定这是否也适用于我的代码。
示例代码:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
var manager = new FooManager();
manager.FooList.Add(new Foo());
manager.FooList.Add(new Foo());
manager.FooList.Add(new Foo());
var updater = new FooUpdater(manager);
updater.UpdateAsync();
}
}
public class FooManager // Singleton
{
public List<Foo> FooList {get;set;}
public FooManager()
{
FooList = new List<Foo>();
}
}
public class Foo
{
public string Value {get; set;}
public async Task UpdateValue(string value)
{
await Task.Delay(10000);
Value = value;
}
}
public class FooUpdater // HostedService
{
private readonly FooManager _foomanager;
public FooUpdater(FooManager foomanager)
{
_foomanager = foomanager;
}
public async Task UpdateAsync()
{
while(true)
{
foreach(var foo in _foomanager.FooList)
{
await foo.UpdateValue("AAA");
}
}
}
}
public class FooController // Api Controller
{
private readonly FooManager _fooManager;
public FooController(FooManager foomanager)
{
_fooManager = foomanager;
}
// ...
// Read or write to foomanager.FooList items value
}
您的代码中有 2 个潜在的线程安全问题
同时从多个线程写入/更新到List<T>
。
解决方案:使用ConcurrentBag<T>
而不是List<T>
,因为您不会通过索引访问项目,这是一个完美的选择。
有可能同时从HostedService
和FooController
更新示例foo
对象( foo.UpdateValue(string)
)。
解决方案:您需要使 foo 类中的UpdateValue
方法线程安全。 抱歉,我无法为您提供示例代码,因为您没有在帖子中提供实际(从简单到实际)的代码。
如果是这样,我是否需要锁定 Foo.Value 或 FooManager.FooList 的 getter/setter?
锁定FooManager.FooList
getter/setter 没有用。 如果类型不是具有原子读/写的类型(例如double
),您应该锁定Foo.Value
,更好地锁定所有类型,但我不认为如果我们不锁定值会被破坏,所以就个人而言我通常不会锁定,因为我不关心线程之间的值一致性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.