gpt4 book ai didi

c# - 防止重入并确保为某些操作获取锁的正确方法是什么?

转载 作者:太空狗 更新时间:2023-10-29 18:09:22 25 4
gpt4 key购买 nike

我正在设计一个基类,当继承该基类时,它将针对多线程环境中的上下文提供业务功能。每个实例都可能有长时间运行的初始化操作,所以我想让对象可重用。为此,我需要能够:

  1. 为这些对象之一分配一个上下文以允许它完成它的工作
  2. 防止对象在已有上下文的情况下被分配新的上下文
  3. 防止某些成员在对象没有上下文时被访问

此外,每个上下文对象都可以由多个工作对象共享。

是否有适合我正在尝试做的事情的正确同步原语?这是我想出的最适合我需要的模式:

private Context currentContext;

internal void BeginProcess(Context currentContext)
{
// attempt to acquire a lock; throw if the lock is already acquired,
// otherwise store the current context in the instance field
}

internal void EndProcess()
{
// release the lock and set the instance field to null
}

private void ThrowIfNotProcessing()
{
// throw if this method is called while there is no lock acquired
}

使用上面的方法,我可以保护不应访问的基类属性和方法,除非对象当前处于处理状态。

protected Context CurrentContext
{
get
{
this.ThrowIfNotProcessing();
return this.context;
}
}

protected void SomeAction()
{
this.ThrowIfNotProcessing();

// do something important
}

虽然我最初是使用 Monitor.Enter和相关函数,但这并不能阻止同线程重入(在原始线程上多次调用 BeginProcess)。

最佳答案

.NET 中有一个不可重入的同步对象,您正在寻找一种信号量。

在您致力于此之前,请先做好准备并问问自己如何才能在同一个线程上再次调用 BeginProcess()。这是非常非常不寻常的,您的代码必须可重入才能发生这种情况。这通常只能发生在具有调度程序循环的线程上,GUI 应用程序的 UI 线程就是一个常见的例子。如果这确实可行并且您实际上使用了信号量,那么您也将不得不处理后果,您的代码将陷入僵局。因为它递归到 BeginProcess 并在信号量上停止。因此永远不会完成也永远无法调用 EndProcess()。 Monitor 和 Mutex 可重入是有充分理由的:)

关于c# - 防止重入并确保为某些操作获取锁的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19016595/

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