Ada*_*ras 8 .net c# multithreading synchronization
我正在设计一个基类,当继承时,它将针对多线程环境中的上下文提供业务功能.每个实例可能具有长时间运行的初始化操作,因此我想使对象可重用.为了做到这一点,我需要能够:
此外,每个上下文对象可以由许多工作对象共享.
是否有正确的同步原语适合我正在尝试做的事情?这是我提出的最符合我需要的模式:
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
}
Run Code Online (Sandbox Code Playgroud)
使用上面的内容,我可以保护不应该访问的基类属性和方法,除非该对象当前处于处理状态.
protected Context CurrentContext
{
get
{
this.ThrowIfNotProcessing();
return this.context;
}
}
protected void SomeAction()
{
this.ThrowIfNotProcessing();
// do something important
}
Run Code Online (Sandbox Code Playgroud)
我的初始是使用Monitor.Enter
和相关的函数,但这不会阻止相同的线程重入(BeginProcess
在原始线程上多次调用).
Han*_*ant 12
.NET中有一个不可重入的同步对象,您正在寻找一个信号量.
在你提交这个之前,确实让你的鸭子连续,并问自己如何在同一个线程上再次调用BeginProcess().这是非常非常不寻常的,你的代码必须重新进入才能实现.这通常只发生在具有调度程序循环的线程上,GUI应用程序的UI线程是一个常见示例.如果这是真的可能,你实际上使用信号量,那么你也将处理后果,你的代码将陷入僵局.因为它递归到BeginProcess并在信号量上停顿.因此永远不会完成,永远不能调用EndProcess().有一个很好的理由可以让Monitor和Mutex重新进入:)
您可以使用Semaphore
.NET Framework 2.0附带的类.
信号量的良好用法是同步有限数量的资源.在您的情况下,您似乎拥有Context
您希望在消费者之间共享的资源.
您可以创建信号量来管理资源,例如:
var resourceManager = new Semaphore(0, 10);
Run Code Online (Sandbox Code Playgroud)
然后BeginProcess
使用以下方法等待方法中的资源可用:
resourceManager.WaitOne();
Run Code Online (Sandbox Code Playgroud)
最后EndProcess
使用以下方法释放方法中的资源:
resourceManager.Release();
Run Code Online (Sandbox Code Playgroud)
这是一个关于在像你这样的情况下使用Semaphores 的好博客:
https://web.archive.org/web/20121207180440/http://www.dijksterhuis.org/using-semaphores-in-c/