kof*_*fus 4 .net c# async-await c#-7.0
我试图找到一种解决方案,用于锁定全局资源,以便锁定访问权限,并且可用于同步或异步操作.
我创建了一个通用类状态:
public class State<T>
{
public class LockedState : IDisposable {
public LockedState(State<T> state) { this.state = state; Monitor.Enter(this.state.theLock); } // would be great if this could be private
public void Dispose() => Monitor.Exit(this.state.theLock);
public ref T Val { get { return ref state.t; } }
readonly State<T> state;
};
public State() { }
public State(T t) { this.t = t; }
public LockedState Locked { get { return new LockedState(this); } }
readonly object theLock = new object();
T t;
}
Run Code Online (Sandbox Code Playgroud)
这里的想法是我可以拥有一个全局"商店",即在Program类中:
public class Program {
static public readonly State<ImmutableList<int>> TheList = new State<ImmutableList<int>>(ImmutableList<int>.Empty);
static public readonly State<SomeType> SomeType = new State<SomeType>(SomeType());
}
Run Code Online (Sandbox Code Playgroud)
然后访问状态的唯一方法是获取这样的锁:
using (var lTheList = Program.TheList.Locked) {
lTheList.Val = lTheList.Val.Add(5));
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下,它比普通的锁更好,因为它在get/set之前强制锁定(你不能忘记锁定)
(旁注是一个好策略?)
问题是我不能在异步代码中使用上面的代码:
using (var someType = Program.SomeType.Lock()) {
var x = await someType.Val.SomeAsyncOp();
}
Run Code Online (Sandbox Code Playgroud)
我得到一个例外: Object synchronization method was called from an unsynchronized block of code
我发现这篇文章如何保护可能在多线程或异步环境中使用的资源?它有一个AsyncLock类但是我无法理解如何将AsyncLock这样的类放入我的StateLock类中.
可以State.Lock()返回可用于同步和异步调用者的锁定状态吗?这才是我真正想要的!
如果不是我最好的前进方向是什么?使用SemaphoreSlim和拥有State.Lock()和State.AsyncLock() ?
谢谢!
你不能Monitor在这里使用,因为Monitor(又名lock)本质上是基于线程的,并且要求你从获得锁的同一个线程中"退出" 锁 - 这正是你在代码中很少期望的情况async.相反,考虑一个SemaphoreSlim,你可以从中获取和释放一个令牌,但它不是线程绑定的.
伪代码:
// usually a field somewhere
SemaphoreSlim obj = new SemaphoreSlim(1);
// acquire lock:
obj.Wait(); // or await obj.WaitAsync() if want async acquire
// release lock:
obj.Release(); // often in a "finally"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
138 次 |
| 最近记录: |