线程只阻止第一个线程

时间:2010-07-10 05:08:14

标签: c# multithreading

我有一个场景,命令通过套接字进入,需要相当多的工作。一次只有一个线程可以处理数据。这些命令的处理速度比处理它的速度快。随着时间的推移,会有一个安静的后退日志。

好的部分是我可以丢弃等待的线程,并且实际上只需要处理正在等待的最后一个 - (或者处理第一个并且丢弃所有其他的一次)。我正在考虑使用信号量来控制代码的关键部分,并使用布尔值来查看是否有任何线程阻塞。如果有阻塞线程,我会丢弃该线程。

我的想法是如何很好地实现它我想实现它,而不是使用整数或布尔值来查看是否有一个线程已经等待。

我在c#

编码

4 个答案:

答案 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();
        }
    }
}

结帐:ManualResetEvent

这是一个有用的线程类。