我有一个带有多个静态方法的静态类。
private static Session _session = new Session();
public static void Method1() {
if(_session != null)
_session.Action();
}
public static void Method2() {
if(_session != null)
_session.Action();
}
public static void Method3() {
if(_session != null)
_session.Action();
}
public static void Method4(string path) {
_session.Disconnect();
_session.Connect(new Config(path));
}
Method1,Method2,Method3是完全线程安全的,可以从任意数量的线程安全地同时调用它们。实际上,出于性能原因,我需要允许多个线程同时调用Method1,2,3。
问题是,当调用Method4()时,Method1,2,3可能会抛出异常。 如何在调用Method4()时允许多个线程调用Method1,2,3同时阻塞它们?
答案 0 :(得分:4)
正如SLaks所指出的,ReadWriterLock是一个很好的解决方案。
以下是我最终实施的内容:
private static ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
private static Session _session = new Session();
public static void Method1() {
_lock.EnterReadLock();
try {
if(_session != null)
_session.Action();
}
finally
{
_lock.ExitReadLock();
}
}
public static void Method2() {
_lock.EnterReadLock();
try {
if(_session != null)
_session.Action();
}
finally
{
_lock.ExitReadLock();
}
}
public static void Method3() {
_lock.EnterReadLock();
try {
if(_session != null)
_session.Action();
}
finally
{
_lock.ExitReadLock();
}
}
public static void Method4(string path) {
_lock.EnterWriteLock();
try {
if(_session != null)
_session.Action();
}
finally
{
_lock.ExitWriteLock();
}
}
性能卓越,没有线程问题!
答案 1 :(得分:0)
private static RefCountDisposable _refCountDisposible = new RefCountDisposable();
private static Session _session = new Session();
public Constructor()
{
_refCountDisposible = new RefCountDisposable(
Disposible.Create(() => _session.Disconnect()));
}
public static void Method1() {
using(_refCountDisposible.GetDisposible())
if(_session != null)
_session.Action();
}
public static void Method2() {
using(_refCountDisposible.GetDisposible())
if(_session != null)
_session.Action();
}
public static void Method3() {
using(_refCountDisposible.GetDisposible())
if(_session != null)
_session.Action();
}
public static void Method4(string path) {
_refCountDisposible.Dispose()
}
答案 2 :(得分:-2)
ManualResetEvent怎么样?
M4()
{
_event.Reset();
try
//reconnect
finally
_event.Set();
}
M1,2,3()
{
_event.WaitOne();
//do actions
}