我正在尝试从多个线程访问一个方法,我不确定这是否是线程安全的。如果不是,确保安全的最有效方法是什么?
我考虑了每个人的见解,我的最终产品如下所示,我还选择对数据包本身进行回收。
我的数据包池类
using System.Collections.Generic;
namespace Networking
{
public class PacketPool
{
private Queue<Packet> pool = new Queue<Packet>();
private readonly object instance = new object();
public Packet CreatePacket(string method)
{
lock (instance)
return pool.Count == 0 ? new Packet() { Pool = this } :
pool.Dequeue();
}
public void Recycle(Packet packet)
{
lock(instance)
pool.Enqueue(packet);
}
}
}
数据包类
using System;
using System.Net;
namespace Networking
{
public class Packet
{
public Protocol Proto = Protocol.Sequenced;
public PacketFlags Flag = PacketFlags.None;
public Fragment Fragmented = Fragment.NotFragged;
public SendType SendType = SendType.Raw;
public EndPoint RemoteEp = new IPEndPoint(IPAddress.Any, 0);
public byte[] Buffer = new byte[512];
public int Count = 0;
public int Ptr = 8;
public int Bits { get; set; } = 0;
public ushort Id = 0;
public ushort Lead = 0;
public PacketPool Pool;
public void Recycle()
{
Bits = 0;
if (Buffer.Length > 512)
Array.Resize(ref Buffer, 512);
Count = 0;
Flag = PacketFlags.None;
Fragmented = Fragment.NotFragged;
Proto = Protocol.Sequenced;
Ptr = 8;
Lead = 0;
SendType = SendType.Raw;
Pool.Recycle(this);
}
}
}
希望上述解决方案能让生活更轻松。
最佳答案
只要数据包本身不在单独的线程上修改,您显示的代码看起来就是线程安全的。您还可以考虑使 PacketPool 类成为线程安全的,以节省一些宝贵的锁定时间。
您可以通过将 Queue
替换为 ConcurrentQueue
来简化它.
请注意,您正在修改发送到Recycle
方法中的数据包。我建议使数据对象不可变,以避免意外行为。
public class PacketPool
{
public ConcurrentQueue<Packet> pool = new ConcurrentQueue<Packet>(2000);
public Packet CreatePacket(string method)
{
if (pool.TryDequeue(out Packet packet))
{
return packet;
}
return new Packet();
}
public void Recycle(Packet packet)
{
packet.Bits = 0;
if (packet.Buffer.Length > 512)
Array.Resize(ref packet.Buffer, 512);
packet.Count = 0;
packet.Flag = PacketFlags.None;
packet.Fragmented = Fragment.NotFragged;
packet.Proto = Protocol.Sequenced;
packet.Ptr = 8;
packet.Lead = 0;
packet.SendType = SendType.Raw;
pool.Enqueue(packet);
}
}
关于c# - 多个线程访问一个返回方法,带锁是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56779841/