問題描述
我怎樣才能優雅地寫 lock {}? (how can I write lock {} elegantly?)
In my multi-threaded project(C# 3.5), I have many codes simliar to this:
Map map;
lock ( _maps )
{
map = _maps.First( i => i.ID == arg.MapID );
}
It looks ugly to me. Takes too many lines for simple retrieval...
What I want is one line code as simple as this:
Map map = _maps.First( i => i.ID == arg.MapID );
But with lock: (not working)
Map map = lock( _maps ){ _maps.First( i => i.ID == arg.MapID ) };
Map map = delegate(){ lock( _maps ) return _maps.First( i => i.ID == arg.MapID ) };
Any help will be greatly appreciated :) Thanks
參考解法
方法 1:
public T Lock<T>(object o, Func<T> f) {
lock (o) {
return f();
}
}
...
Map map = Lock(_maps, () => _maps.First(i => i.ID == arg.MapID));
方法 2:
Better yet, just make an extension method on Object
instead of IEnumerable<T>
:
public static T LockAndExecute<T>(this Object obj, Func<T> operation)
{
lock(obj)
{
return operation();
}
}
That way not only is your case elegant
Map map = _maps.LockAndExecute(() => _maps.First(i => i.ID == arg.MapID);
but you can reuse this regardless of what you're doing within the lock.
方法 3:
If you think it looks better on one line,
Map map; lock( _maps ){ map = _maps.First( i => i.ID == arg.MapID ) };
is only another 4 characters to what you've tried. But it's the same as what you currently have, just on one line.
方法 4:
you can use an extension method...
public static TResult Lock<T, TResult>(this T arg,
Func<T, TResult> callback) where T : class
{
if(arg == null) throw new ArgumentNullException();
lock(arg)
{
return callback(arg);
}
}
and you can use it like this
Map map = maps.Lock(x => x.First( i => i.ID == arg.MapID ));
方法 5:
With a function like this:
static class WithLock
{
public static T Execute<T>(object o, Func<T> action)
{
lock (o)
{
return action();
}
}
}
you can do something like this:
Map map = WithLock.Execute(_maps, () => _maps.First( i => i.ID == arg.MapID ));
(by Vincent、J.D.、Paul Wheeler、Kirk Broadhurst、aqwert、Gabe)