发个同步锁的代码。欢迎来看看不足的地方。

lostinetdotcom 2003-07-22 09:02:31
using System;
using System.Diagnostics;

#region class Lostinet.HashCodeLock
namespace Lostinet
{
using System;
using System.Collections;
using System.Reflection;
using System.Threading;
using System.Diagnostics;

#region class HashCodeLock
[Serializable] public sealed class HashCodeLockTimeoutException:Exception
{
public HashCodeLockTimeoutException(string msg):base(msg){}
}
public sealed class HashCodeLock : MarshalByRefObject
{
#region class Allocator
class Allocator
{
ArrayList al=new ArrayList();
public object Alloc(object obj)
{
object n=obj;
lock(al.SyncRoot)
{
int index=al.IndexOf(n);
if(index!=-1)
{
n=al[index];
}
al.Add(n);
return n;
}
}
public object Release(object obj)
{
object n=obj;
lock(al.SyncRoot)
{
int index=al.IndexOf(n);
if(index==-1)
throw(new Exception("cant release obj:node not found"));
n=al[index];
al.RemoveAt(index);
return n;
}
}
}
#endregion

#region class InternalLock
class InternalLock:IDisposable
{
HashCodeLock h;
object o;
public InternalLock(HashCodeLock hcl,object obj,int timeout)
{
object syncobj=hcl.ac.Alloc(obj);
bool enterok=false;
try
{
enterok=Monitor.TryEnter(syncobj,timeout);
if(!enterok)
throw(new HashCodeLockTimeoutException("lock timeout"));
}
finally
{
if(!enterok)
hcl.ac.Release(obj);
}
h=hcl;
o=obj;
SetStackTrace();
}

string s=" unknown method (not query in release) ";
[Conditional("DEBUG")]
void SetStackTrace()
{
try
{
StackTrace st=new StackTrace(3);//skip at lease 3 frame
for(int i=0;i<st.FrameCount;i++)
{
MethodBase mb=st.GetFrame(i).GetMethod();
if(mb.ReflectedType!=typeof(HashCodeLock))
{
s=mb.ReflectedType.FullName+":"+mb.ToString();
return;
}
}
}
catch
{
}
}

public void Dispose()
{
if(h==null)
throw(new Exception("lock at "+s+" already released!"));
Monitor.Exit(h.ac.Release(o));
h=null;
o=null;
}
~InternalLock()
{
if(h!=null)
{
try
{
//回收对象。但无法使用Monitor.Exit
h.ac.Release(o);
//不同的线程了,Monitor.Exit(h.ac.Release(o));不起作用
}
finally
{
throw(new Exception("lock at "+s+" have not released!"));
}
}
}
}
#endregion

#region instance
Allocator ac=new Allocator();

public IDisposable Lock(object obj)
{
if(obj==null)throw(new ArgumentNullException("obj"));
return new InternalLock(this,obj,Timeout.Infinite);
}
public IDisposable Lock(object obj,int msTimeout)
{
if(obj==null)throw(new ArgumentNullException("obj"));
return new InternalLock(this,obj,msTimeout);
}
public IDisposable Lock(object obj,TimeSpan tsTimeout)
{
if(obj==null)throw(new ArgumentNullException("obj"));
return new InternalLock(this,obj,(int)tsTimeout.TotalMilliseconds);
}
#endregion

#region static
static HashCodeLock hcl=new HashCodeLock();
/// <summary>
/// 用于全局的HashCodeLock
/// </summary>
static public HashCodeLock GlobalLock
{
get
{
return hcl;
}
}
#endregion
}
#endregion
}
#endregion

namespace ConsoleApplication1
{
using System;
using System.Collections;
using System.Data;
using System.IO;
using System.Threading;
using System.Text;

using Lostinet;

class Class1
{
static ManualResetEvent mre=new ManualResetEvent(false);

[MTAThread]
static void Main(string[] args)
{
//启动10条线程
for(int i=0;i<10;i++)
new Thread(new ThreadStart(
new Job(i).Start
))
.Start();

Thread.Sleep(1000);
Console.WriteLine("Start!");
mre.Set();
}

class Job
{
///用于同步任务的私有锁
static HashCodeLock JobLock=new HashCodeLock();

int i;
public Job(int index)
{
i=index;
}
public void Start()
{
mre.WaitOne();
//随机等待一些时间。打乱Job的顺序
Thread.Sleep(new Random(i*DateTime.Now.Millisecond).Next(20));

int ms=3000;//默认等待3秒

if(i==5)
ms=300; //index5任务超时(如果它不是前2位执行的Job)

// if(i==8)
// {
// //错误的用法!..没有使用using..
// JobLock.Lock( int.Parse("11") );
// GC.Collect();
// }

try
{
//换成相等当不同引用的string就无法锁住。。
//lock(11.ToString())

//可以使用全局的HashCodeLock
//using(HashCodeLock.GlobalLock.Lock( int.Parse("11") , ms ))

//JobLock是私有的,假如程序有其他地方使用了HashCodeLock也不会进行锁定的冲突。
using(JobLock.Lock( int.Parse("11") , ms ))
{
Thread.Sleep(100);
Console.WriteLine("job:"+i+" ok");
Thread.Sleep(100);
}
}
catch(Exception x)
{
Console.WriteLine("job:"+i+" - "+x.GetType().FullName+":"+x.Message);
}
}
}
}
}

...全文
82 6 打赏 收藏 举报
写回复
6 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
cnhgj 2003-07-24
  • 打赏
  • 举报
回复
还没看我的眼睛就变这样@_@了!呵呵!!
lostinetdotcom 2003-07-24
  • 打赏
  • 举报
回复
对啊。我是发在讨论区的.
有没有搞错啊~~~`
还说讨论区允许发帖.
我这帖又不是问问题的。
讨论区很多帖吗?
好忙吗?
也不知道谁看也不看就搬到这里来。
~~~
aspcn 2003-07-23
  • 打赏
  • 举报
回复
太长了!!!
刚刚看你是发在讨论区的,咋到这里来了?
snewxf 2003-07-23
  • 打赏
  • 举报
回复
呵呵!这到是!有点晕!
ynnwq 2003-07-23
  • 打赏
  • 举报
回复
一个字,晕
写点简单的呀
  • 打赏
  • 举报
回复
gz
相关推荐
发帖
C#

10.8w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
帖子事件
创建了帖子
2003-07-22 09:02
社区公告

让您成为最强悍的C#开发者