C# 保证线程完成的空锁

C# 保证线程完成的空锁,c#,multithreading,locking,C#,Multithreading,Locking,我的c#服务如下所示: public partial class MyService : ServiceBase { private object @lock = new object(); private CancellationTokenSource cancellationSource = new CancellationTokenSource(); private Timer timer = new Timer(Worker, null, 0, 20*1000)

我的c#服务如下所示:

public partial class MyService : ServiceBase 
{
    private object @lock = new object();
    private CancellationTokenSource cancellationSource = new CancellationTokenSource();
    private Timer timer = new Timer(Worker, null, 0, 20*1000);

    private void Worker(Object stateInfo)
    {
        lock (@lock) {
            if (cancellationSource.IsCancellationRequested)
                return;

            //code that must not execute after OnStop

        }
    }

    protected override void OnStop()
    {
        cancellationSource.Cancel();

        lock (@lock) {}

        //Worker is guaranteed not to execute any more code here
    }

}
正如您所看到的,Worker不应该在OnStop之后再运行任何代码,我认为空锁可以解决这个问题,因为即使Worker在它之后进入锁,它也会立即退出,这是由于取消令牌


然而,我从未见过空锁,所以我担心我错过了一些东西。是吗?

锁在这里没有目标。通过使用
任务
,可以更好地完成您想要实现的目标:

Task.Run(Worker, cancellationToken);

如果计时器被触发,取消令牌将立即停止任务的进一步运行。

锁在这里不起作用。通过使用
任务
,可以更好地完成您想要实现的目标:

Task.Run(Worker, cancellationToken);


如果计时器被触发,取消令牌将立即停止任务进一步运行。

我认为这不会满足您的要求。如果您已经处于锁定工作区,那么您只需等待顶部的锁定
。它不会把锁从工人或类似的地方拿走。我想你需要去读一下锁的工作原理。我猜这将意味着在
OnStop
返回后,worker中不会运行任何东西,但我不知道延迟
OnStop
是否真的是您想要的…@Chris这正是我想要的-应该等到worker完成。我需要的是,当OnStop返回,services.msc显示我的服务已停止时,我可以确定Worker没有运行。啊,那么也许这会满足您的要求,尽管我不确定是否有更好的方法。为什么您不能删除
?帕特里克霍夫曼,这样当OnStop退出时,我可以确定工人不再运行了。我认为这不会满足你们的要求。如果您已经处于锁定工作区,那么您只需等待顶部的锁定
。它不会把锁从工人或类似的地方拿走。我想你需要去读一下锁的工作原理。我猜这将意味着在
OnStop
返回后,worker中不会运行任何东西,但我不知道延迟
OnStop
是否真的是您想要的…@Chris这正是我想要的-应该等到worker完成。我需要的是,当OnStop返回,services.msc显示我的服务已停止时,我可以确定Worker没有运行。啊,那么也许这会满足您的要求,尽管我不确定是否有更好的方法。为什么您不能删除
?这里没有任何用途。帕特里克霍夫曼说,当停止出口时,我可以确信工人不再运行。我不想让工人在中间放弃。这就是你的代码所说的。您不希望让代码在某一点之后运行。那个么你们想要的是什么呢?那个么在顶部应该等到工人完成。如果停止使用services.msc,您将看到停止。。。只要Worker正在运行。然后将所有Worker
Task
s放入一个列表中,并
Task.WaitAll(tasks)代码> OnStop <代码>。如何在列表中放置一个由一个定时器触发的工作人员?我不想在中间放弃工作人员。这是您的代码所说的。您不希望让代码在某一点之后运行。那个么你们想要的是什么呢?那个么在顶部应该等到工人完成。如果停止使用services.msc,您将看到停止。。。只要Worker正在运行。然后将所有Worker
Task
s放入一个列表中,并
Task.WaitAll(tasks)
桌面上
中。如何将计时器触发的工作进程放入列表中?