C# 锁定IHostedService
我有C# 锁定IHostedService,c#,multithreading,asp.net-core,C#,Multithreading,Asp.net Core,我有IHostedServiceinheritor服务,处理一些数据,并将最后一部分存储在变量中 public class MyService : IHostedService { private DataType lastData; public DataType GetLastData() { return lastData; } public void ProcessNextPart() { ...
IHostedService
inheritor服务,处理一些数据,并将最后一部分存储在变量中
public class MyService : IHostedService
{
private DataType lastData;
public DataType GetLastData()
{
return lastData;
}
public void ProcessNextPart()
{
...
}
}
我还有api控制器,它使用DI调用MyService
。
在这种情况下,我应该对lastData
使用lock
还是其他方法?据我所知,可以同时读取(从控制器)和写入(从服务)该变量吗
谢谢。这取决于
数据类型是类还是结构
如果它是一个类,那么编写它是原子的,所以它非常安全。如果您认为调用方可以在循环中使用该值,那么您可能需要添加一个易失性读取,以防止该值被缓存在寄存器中:
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字节),则写入它不是原子的。即使struct足够小,我也不建议依赖它,因为您可以稍后添加更多字段并破坏此代码。所以有两种解决方案:要么使用锁,要么将值框起来
使用锁:
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);
}
}
使用System.Runtime.CompilerServices;
公共类MyService:IHostedService
{
私有只读对象syncRoot=新对象();
私人保险箱数据;
公共数据类型GetLastData()
{
返回lastData.Value;
}
public void ProcessNextPart()
{
lastData=新的保险箱(newValue);
}
}
MyService的目的是什么?对于IHostedService
,它用于处理长任务或与请求无关的任务。您需要从controller调用MyService
的原因是什么?作为托管服务,您希望在MyService中实现什么,以及您希望通过MyService从controller中实现什么?MyService与请求无关,它在后台进行计算。客户端可以使用控制器请求处理数据的最后一部分。所以关键是多线程使用变量,最后一部分存储在这里。如果DataType
是一个类,没有任何锁定机制就可以了。如果它是一个结构,那么编写它可能不是原子的,在这种情况下,您应该添加一个锁或值框谢谢您的回答。对于List和nullable(例如int?)来说,第一种情况是真的吗?List
是一个类,所以它是第一种情况Nullable
是一个结构,所以第二种情况