gpt4 book ai didi

c# - 如何只让一个线程运行临界区,同时丢弃其他线程而不挂起

转载 作者:行者123 更新时间:2023-11-30 22:05:22 26 4
gpt4 key购买 nike

我正在使用 .NET Framework 4.0 和 C# 开发 Windows 服务。

此服务将打开一个套接字来接收命令。

我有这个套接字监听器类:

public class SocketListener
{
private System.Net.Sockets.TcpListener m_server;

public SQLServerSocketListener()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, 5445);
m_server = new System.Net.Sockets.TcpListener(ip);
}

public void Start()
{
m_server.Start();
m_server.BeginAcceptTcpClient(new AsyncCallback(Callback), m_server);
}

public void Stop()
{
if (m_server != null)
m_server.Stop();
}

private void Callback(IAsyncResult ar)
{
if (!(m_server.Server.IsBound) ||
(m_server.Server == null))
return;

TcpClient client;
try
{
client = m_server.EndAcceptTcpClient(ar);
}
catch (ObjectDisposedException)
{
//Listener canceled
return;
}
DataHandler dataHandler = new DataHandler(client);
ThreadPool.QueueUserWorkItem(dataHandler.HandleClient, client);

m_server.BeginAcceptTcpClient(new AsyncCallback(Callback), m_server);
}
}

这个类处理通过套接字接收到的命令:

class DataHandler
{
private bool m_disposed = false;
private TcpClient m_controlClient;

private IPEndPoint m_remoteEndPoint;
private string m_clientIP;

private NetworkStream m_controlStream;
private StreamReader m_controlReader;

public DataHandler(TcpClient client)
{
m_controlClient = client;
}

public void HandleClient(object obj)
{
m_remoteEndPoint = (IPEndPoint)m_controlClient.Client.RemoteEndPoint;

m_clientIP = m_remoteEndPoint.Address.ToString();

m_controlStream = m_controlClient.GetStream();

m_controlReader = new StreamReader(m_controlStream, true);

string line;
try
{
while (((line = m_controlReader.ReadLine()) != null) ||
(m_controlClient == null) ||
(!m_controlClient.Connected))
{
CommandHandler.ProcessCommand(line);
}
}
catch (Exception ex)
{
Console.WriteLine("CodeServerService.DataHandler error: {0}", ex.Message);
}
finally
{
Dispose();
}
}
}

还有,CommandHandler:

class CommandHandler
{
public static void ProcessCommand(string command, string connStringINICIC, string connStringTRZIC, byte codeLevel)
{
switch (command)
{
case "GetNewCodes<EOF>":
CodesIncremental.GetNewCodes();
break;
}
}
}

CodesIncremental :

public class CodesIncremental
{
public static bool GetNewCodes()
{
[ ... ]
}
}

我的问题是我可以收到 GetNewCodes<EOF>在第一个完成之前发出命令。所以,我需要不让 GetNewCodes<EOF>如果有另一个 GetNewCodes<EOF> 则运行运行。

我怎么能不让跑CodesIncremental.GetNewCodes();如果此代码在另一个线程中运行?

我需要一些东西来丢弃 CodesIncremental.GetNewCodes(); 时收到的命令正在运行。

在伪代码中:

如果CodesIncremental.GetNewCodes();正在运行什么都不做。

最佳答案

此版本不阻塞。 CompareExchange确保原子性,因此只有一个线程会交换 _running 变量的值,其余线程会立即返回。

public class CodesIncremental
{
static Int32 _running = 0;

public static bool GetNewCodes()
{
if (Interlocked.CompareExchange(ref _running, 1, 0) == 1)
return false;

try
{
// Do stuff...
return true;
}
finally
{
_running = 0;
}
}
}

与监视器或其他同步方法不同的是,此方法几乎没有争用,而且速度相当快。

关于c# - 如何只让一个线程运行临界区,同时丢弃其他线程而不挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24427367/

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