[英]How can I write the following code more elegantly using LINQ query syntax?
[英]how can I write lock {} elegantly?
在我的多線程項目(C#3.5)中,我有許多與此類似的代碼:
Map map;
lock ( _maps )
{
map = _maps.First( i => i.ID == arg.MapID );
}
對我來說看起來很丑。 需要太多行來進行簡單檢索...
我想要的是這樣一個簡單的行代碼:
Map map = _maps.First( i => i.ID == arg.MapID );
但是帶鎖:(不起作用)
Map map = lock( _maps ){ _maps.First( i => i.ID == arg.MapID ) };
Map map = delegate(){ lock( _maps ) return _maps.First( i => i.ID == arg.MapID ) };
任何幫助將不勝感激:)謝謝
public T Lock<T>(object o, Func<T> f) {
lock (o) {
return f();
}
}
...
Map map = Lock(_maps, () => _maps.First(i => i.ID == arg.MapID));
更好的是,只需對Object
而不是IEnumerable<T>
做一個擴展方法:
public static T LockAndExecute<T>(this Object obj, Func<T> operation)
{
lock(obj)
{
return operation();
}
}
這樣不僅可以使您的案子優雅
Map map = _maps.LockAndExecute(() => _maps.First(i => i.ID == arg.MapID);
但是無論您在鎖中做什么,都可以重用它。
如果您認為某一行看起來更好,
Map map; lock( _maps ){ map = _maps.First( i => i.ID == arg.MapID ) };
只是您嘗試過的另外4個字符。 但這與您當前擁有的相同,只是一行。
您可以使用擴展方法...
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);
}
}
你可以這樣使用
Map map = maps.Lock(x => x.First( i => i.ID == arg.MapID ));
具有這樣的功能:
static class WithLock
{
public static T Execute<T>(object o, Func<T> action)
{
lock (o)
{
return action();
}
}
}
您可以執行以下操作:
Map map = WithLock.Execute(_maps, () => _maps.First( i => i.ID == arg.MapID ));
丑陋? 我不這么認為。 也許您可以改用它,它們是完全一樣的。
Monitor.Enter(obj);
try
{
//do something
}
finally
{
Monitor.Exit(obj);
}
但我更喜歡lock
語句,因為{}
提供了更清晰的范圍。
lock(obj)
{
//body of the lock statement
}//end of the lock scope
更清楚了,不是嗎? 你為什么覺得丑?
嘗試一些沒有擴展方法的簡單操作
private static readonly object lockObj = new object();
private static T LockAndExecute<T>(Func<T> func)
{
lock (lockObj)
return func();
}
Map map = LockAndExecute(() => _maps.First(i => i.ID == arg.MapID));
我真的不喜歡其他答案中提供的任何選項。 所提出的方法依賴於呼叫者對方法內部的了解,並且呼叫站點的復雜性對於該方法打算執行的操作而言太高了。 這兩個都是主要的代碼氣味。
相反,為什么不只是在正確的抽象級別上創建明顯的方法呢? 然后,您的代碼將下降到一條簡單的代碼行。
private Map GetMapById(int id)
{
lock (_maps)
{
return _maps.First( i => i.ID == id );
}
}
....
Map map = GetMapById(arg.MapID);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.