C# 遇到锁时如何停止线程?

C# 遇到锁时如何停止线程?,c#,.net,multithreading,locking,C#,.net,Multithreading,Locking,我有以下启动一些线程的代码: List<Stuff> lNewStuff = new List<Stuff>(); // populate lNewStuff for (int i = 0; i < accounts.Length; i++) { Account aTemp = _lAccounts.Find(item => item.ID == accounts[i]); Thread t

我有以下启动一些线程的代码:

    List<Stuff> lNewStuff = new List<Stuff>();

    // populate lNewStuff

    for (int i = 0; i < accounts.Length; i++)
    {
        Account aTemp = _lAccounts.Find(item => item.ID == accounts[i]);

        Thread tTemp = new Thread(() => aTemp.ExecuteMe(lNewStuff));
        tTemp.Start();     
    }
List lNewStuff=new List();
//填充lNewStuff
for(int i=0;iitem.ID==accounts[i]);
Thread tTemp=新线程(()=>aTemp.ExecuteMe(lNewStuff));
tTemp.Start();
}
然后在Account类中有一个带有锁的ExecuteMe方法:

    public class Account
    {
        private Object lockThis = new Object();

        public void ExecuteMe(List<Stuff> lNewStuff)
        {
            //Ensure only one thread at a time can run this code
            lock (lockThis)
            {
                //main code processing
            }
        }
    }
公共类帐户
{
私有对象锁定this=新对象();
public void ExecuteMe(列表lNewStuff)
{
//确保一次只有一个线程可以运行此代码
锁定(锁定此)
{
//主代码处理
}
}
}
现在,有时线程以lNewStuff==null开始,因为它有时找不到任何具有帐户ID的新内容。这对于这个项目来说是正常的。该线程应该总是尝试运行,但当null为空时,我希望该线程停止运行,而不是在遇到锁时等待

具体而言:

如果lNewStuff为null且存在锁,则终止线程。(怎么做?)

如果lNewStuff为null且没有锁,则正常运行(是否已经运行)

如果lNewStuff不为null且存在锁,则等待锁完成(是否已完成)


如果lNewStuff不为null且没有锁,则正常运行(是否已经运行)

lNewStuff
为null时,您可以使用,并且只有在授予锁后才能继续:

public class Account
{
    private readonly object lockThis = new object();

    public void ExecuteMe(List<Stuff> lNewStuff)
    {
        bool lockTaken = false;
        try
        {
            if (lNewStuff == null)
            {
                // non-blocking - only takes the lock if it's available
                Monitor.TryEnter(lockThis, ref lockTaken);
            }
            else
            {
                // blocking - equivalent to the standard lock statement
                Monitor.Enter(lockThis, ref lockTaken);
            }

            if (lockTaken)
            {
                // main code processing
            }
        }
        finally
        {
            if (lockTaken)
            {
                Monitor.Exit(lockThis);
            }
        }
    }
}
公共类帐户
{
私有只读对象锁定this=新对象();
public void ExecuteMe(列表lNewStuff)
{
bool-locktake=false;
尝试
{
if(lNewStuff==null)
{
//非阻塞-仅在锁可用时使用锁
监视器.TryEnter(锁定此,参考锁定);
}
其他的
{
//阻塞-相当于标准的lock语句
监视器。输入(锁定此,参考锁定);
}
如果(已锁定)
{
//主代码处理
}
}
最后
{
如果(已锁定)
{
监视器。退出(锁定此);
}
}
}
}
只是为了与众不同:

public class Foo : IDisposable
{
    private Semaphore _blocker;
    public Foo(int maximumAllowed)
    {
        _blocker = new Semaphore(1,1);
    }

    public void Dispose()
    {
        if(_blocker != null)
        {
            _blocker.Dispose();
            _blocker.Close();
        }
    }

    public void LimitedSpaceAvailableActNow(object id)
    {
        var gotIn = _blocker.WaitOne(0);
        if(!gotIn)
        {
            Console.WriteLine("ID:{0} - No room!", id);
            return;
        }
        Console.WriteLine("ID:{0} - Got in! Taking a nap...", id);
        Thread.Sleep(1000);
        _blocker.Release();
    }
}
试验台:

void Main()
{
    using(var foo = new Foo(1))
    {
        Enumerable.Range(0, 10)
            .Select(t => 
                Tuple.Create(t, new Thread(foo.LimitedSpaceAvailableActNow)))
            .ToList()
            .AsParallel()
            .ForAll(t => t.Item2.Start(t.Item1));
        Console.ReadLine();
    }
}
输出:

ID:4 - Got in! Taking a nap...
ID:8 - No room!
ID:0 - No room!
ID:7 - No room!
ID:2 - No room!
ID:6 - No room!
ID:5 - No room!
ID:9 - No room!
ID:1 - No room!
ID:3 - No room!

@LukeH:这是如何确保OP要求的线程终止的,如果您创建多个帐户对象,关键代码是如何得到保护的,这正是我想要的。聪明的做法是,不要真的杀死线程,而是在有块的时候跳出。知道你在锁块中做什么会很有帮助。如果lNewStuff为null,您可能只想从ExecuteMe返回,而不带锁——但是,我们不知道,您还没有提供详细信息。
void Main()
{
    using(var foo = new Foo(1))
    {
        Enumerable.Range(0, 10)
            .Select(t => 
                Tuple.Create(t, new Thread(foo.LimitedSpaceAvailableActNow)))
            .ToList()
            .AsParallel()
            .ForAll(t => t.Item2.Start(t.Item1));
        Console.ReadLine();
    }
}
ID:4 - Got in! Taking a nap...
ID:8 - No room!
ID:0 - No room!
ID:7 - No room!
ID:2 - No room!
ID:6 - No room!
ID:5 - No room!
ID:9 - No room!
ID:1 - No room!
ID:3 - No room!