Mr.*_*ame 4 .net remoting multithreading functional-programming declarative
我需要使现有的应用程序线程安全.在适当的情况下(见下文),我决定在整个业务对象图中使用一个ReaderWriterLock.所有方法/属性必须如下所示:
public int MyReadOperation(string inputParam)
{
rwLock.AcquireReaderLock(10000);
try
{
// do all read operations
...
}
finally
{
rwLock.ReleaseReaderLock();
}
}
public void MyWriteOperation(string input)
{
rwLock.AcquireWriterLock(10000);
try
{
// do all write operations
...
}
finally
{
rwLock.ReleaseWriterLock();
}
}
Run Code Online (Sandbox Code Playgroud)
但是我有很多方法可以覆盖,我从复制/粘贴的想法中吓坏了.受MethodImplAttribute的启发,我希望有一个这样的代码,同时表现为上面的代码:
[ReadOperation]
public int MyReadOperation(string inputParam)
{
// do all read operations
...
}
[WriteOperation]
public void MyWriteOperation(string input)
{
// do all write operations
...
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在进入属性或方法之前/之后中断线程执行并添加线程安全预防措施?或者以某种方式利用C#的函数式语言特性,将方法的生产体嵌入到通用的ReaderWriterLock中获取"框架"?
一点背景:
我正在开发一个项目,通过.NET Remoting公开数据载体业务对象.但是,这些数据类不是可序列化的,而是MarshalByRef-s.这意味着所有客户端实际上读/写相同的业务对象.这是不可改变的,它是刻在石头上的.线程安全的希望是这些远程业务对象在远程客户端的眼中是只读的(认为它们会循环许多列表)并且所有写入操作都很好地分成专用的外观.我希望罕见的写入和频繁的读取.业务对象高度连接,它们非常"图形化".
我会使用PostSharp做类似的事情.
它作为一个额外的构建步骤运行并插入相应的MSIL,但它会做你想要的.PostSharp属性定义看起来像这样(取决于您的确切实现).然后可以如上所述使用它们.
public sealed class ReadOperationAttribute : OnMethodBoundaryAspect
{
// not quite sure how you manage your lock, so put this dummy method in.
ReaderWriterLock _rwLock = ReaderWriterLock.GetCorrectReaderWriterLock();
[ThreadStatic]
static bool _isLocked;
public override void OnEntry( MethodExecutionEventArgs e )
{
try
{
_rwLock.AcquireReaderLock(10000);
_isLocked = true;
}
catch
{
_isLocked = false;
throw;
}
}
public override void OnExit( MethodExecutionEventArgs e )
{
if (_isLocked)
{
_rwLock.ReleaseReaderLock();
_isLocked = false;
}
}
}
public sealed class WriteOperationAttribute : OnMethodBoundaryAspect
{
// not quite sure how you manage your lock, so put this dummy method in.
ReaderWriterLock _rwLock = ReaderWriterLock.GetCorrectReaderWriterLock();
[ThreadStatic]
static bool _isLocked;
public override void OnEntry( MethodExecutionEventArgs e )
{
try
{
_rwLock.AcquireWriterLock(10000);
_isLocked = true;
}
catch
{
_isLocked = false;
throw;
}
}
public override void OnExit( MethodExecutionEventArgs e )
{
if (_isLocked)
{
_rwLock.ReleaseReaderLock();
_isLocked = false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:更新以解决问题.(未经测试;))另外,请注意我在这个问题的评论称,微软建议使用ReaderWriterLockSlim优先于ReaderWriterLock.
首先,谢谢安德鲁(Andrew),他把我指向了 PostSharp。根据他的回答,我得出了最后一个答案。
[Serializable]
public class ReadOperationAttribute : PostSharp.Laos.OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
ReaderWriterLock rwLock = GetLock();
rwLock.AcquireReaderLock(10000);
try { eventArgs.Proceed(); }
finally { rwLock.ReleaseReaderLock();}
}
}
public class Foo
{
[ReadOperation]
public string Bar
{
get { return "stuff"; }
set { Console.WriteLine(value); }
}
[ReadOperation]
public void Test(string input)
{
Console.WriteLine(input);
}
}
Run Code Online (Sandbox Code Playgroud)
它完全符合我在问题中表达的内容,并且完全可以调试。如果我们声明整个程序集的属性,我们可以使其更加有用:
[assembly: ReadOperation(AttributeTargetElements=MulticastTargets.Method,
AttributeTargetTypes="MyNamespace.*")]
Run Code Online (Sandbox Code Playgroud)
这样,我们不必修饰每个方法/属性,但是将这个属性放置在程序集中一次后,便可以使用ReaderWriterLock制动所有方法/属性。
另外,正如Andrew所指出的那样,如果您使用.NET3.5或更高版本,Microsoft建议使用ReaderWriterLockSlim。
| 归档时间: |
|
| 查看次数: |
671 次 |
| 最近记录: |