我有一个场景,命令通过套接字进入,需要相当多的工作。一次只有一个线程可以处理数据。这些命令的处理速度比处理它的速度快。随着时间的推移,会有一个安静的后退日志。
好的部分是我可以丢弃等待的线程,并且实际上只需要处理正在等待的最后一个 - (或者处理第一个并且丢弃所有其他的一次)。我正在考虑使用信号量来控制代码的关键部分,并使用布尔值来查看是否有任何线程阻塞。如果有阻塞线程,我会丢弃该线程。
我的想法是如何很好地实现它我想实现它,而不是使用整数或布尔值来查看是否有一个线程已经等待。
我在c#
编码答案 0 :(得分:1)
我相信你正在寻找锁定声明。
private readonly object _lock = new object();
private void ProccessCommand(Command command)
{
lock (_lock)
{
// ...
}
}
答案 1 :(得分:1)
您可以使用Monitor.TryEnter
查看是否已对对象执行锁定:
void ProcessConnection(TcpClient client)
{
bool lockTaken = false;
Monitor.TryEnter(lockObject, out lockTaken);
if (!lockTaken)
{
client.Close();
return;
}
try
{
// long-running process here
}
finally
{
Monitor.Exit(lockObject);
client.Close();
}
}
请注意,要使其工作,您仍然需要在线程中调用该方法,例如:
client = listener.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(notused => ProcessConnection(client));
仅供参考,lock
声明只是糖:
Monitor.Enter(lockObject);
try
{
// code within lock { }
}
finally
{
Monitor.Exit(lockObject);
}
答案 2 :(得分:0)
听起来你只需要使用lock
语句。 lock
语句中的代码只允许一个线程同时在代码块内工作。
更多信息:lock Statement
答案 3 :(得分:0)
根据你在这里发布的声音,你可能可以避免这么多等待线程。您可以排队执行下一个命令,而不是让线程保持等待,只需在当前命令完成后替换命令以执行next。更换和删除“等待”命令时锁定。
这样的事情:
class CommandHandler
{
Action nextCommand;
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
object lockObject = new object();
public CommandHandler()
{
new Thread(ProcessCommands).Start();
}
public void AddCommand(Action nextCommandToProcess)
{
lock (lockObject)
{
nextCommand = nextCommandToProcess;
}
manualResetEvent.Set();
}
private void ProcessCommands()
{
while (true)
{
Action action = null;
lock (lockObject)
{
action = nextCommand;
nextCommand = null;
}
if (action != null)
{
action();
}
lock (lockObject)
{
if(nextCommand != null)
continue;
manualResetEvent.Reset();
}
manualResetEvent.WaitOne();
}
}
}
这是一个有用的线程类。