我有IHostedService
继承者服务,可以处理一些数据,并将最后一部分存储在变量中。
public class MyService : IHostedService
{
private DataType lastData;
public DataType GetLastData()
{
return lastData;
}
public void ProcessNextPart()
{
...
}
}
我还有api控制器,该控制器使用DI来调用MyService
。
在这种情况下,我应该对lock
使用lastData
还是其他方法?据我了解,可以同时读取(从控制器)和写入(从服务)该变量吗?
谢谢。
答案 0 :(得分:1)
这完全取决于DataType
是类还是结构。
如果它是一个类,则编写它是原子的,因此非常安全。如果您认为调用方可以在循环中使用该值,那么您可能希望添加一个易失性读取,以防止将该值缓存在寄存器中:
public class MyService : IHostedService
{
private DataType lastData;
public DataType GetLastData()
{
return Volatile.Read(ref lastData);
}
public void ProcessNextPart()
{
lastData = newValue;
}
}
但是考虑到用例,这听起来不太可能。
如果DataType
是一个结构,则完全不同。如果该结构大于目标体系结构指针大小(x86为4字节,x64为8字节),则写入不是原子的。即使该结构足够小,我也不建议您依赖它,因为您以后可以添加更多字段并破坏此代码。因此,您有两种解决方案:要么使用锁,要么将值装箱。
使用锁:
public class MyService : IHostedService
{
private readonly object syncRoot = new object();
private DataType lastData;
public DataType GetLastData()
{
lock (syncRoot)
return lastData;
}
public void ProcessNextPart()
{
lock (syncRoot)
lastData = newValue;
}
}
装箱值:
using System.Runtime.CompilerServices;
public class MyService : IHostedService
{
private readonly object syncRoot = new object();
private StrongBox<DataType> lastData;
public DataType GetLastData()
{
return lastData.Value;
}
public void ProcessNextPart()
{
lastData = new StrongBox<DataType>(newValue);
}
}