gpt4 book ai didi

c# - 监视器似乎没有锁定对象

转载 作者:行者123 更新时间:2023-11-30 14:31:24 26 4
gpt4 key购买 nike

我正在尝试实现一个基本的 Future 类(是的,我知道 Task 但这是出于教育目的)并遇到了 的奇怪行为监控类。该类的实现使其进入构造函数中的锁,将退出锁的操作排队到线程池。结果 getter 检查实例变量以查看操作是否完成,如果未完成,则进入锁定,然后返回结果。问题是,实际上结果 getter 不会等待排队的操作完成并继续进行,从而导致不正确的结果。这是代码。

// The class itself
public class Future<T>
{
private readonly Func<T> _f;
private volatile bool _complete = false;
private T _result;
private Exception _error = new Exception("WTF");
private volatile bool _success = false;
private readonly ConcurrentStack<Action<T>> _callbacks = new ConcurrentStack<Action<T>>();
private readonly ConcurrentStack<Action<Exception>> _errbacks = new ConcurrentStack<Action<Exception>>();
private readonly object _lock = new object();

public Future(Func<T> f)
{
_f = f;
Monitor.Enter(_lock);
ThreadPool.QueueUserWorkItem(Run);
}

public void OnSuccess(Action<T> a)
{
_callbacks.Push(a);
if (_complete && _success)
a(_result);
}

public void OnError(Action<Exception> a)
{
_errbacks.Push(a);
if (_complete && !_success)
a(_error);
}

private void Run(object state)
{
try {
_result = _f();
_success = true;
_complete = true;
foreach (var cb in _callbacks) {
cb(_result);
}
} catch (Exception e) {
_error = e;
_complete = true;
foreach (var cb in _errbacks) {
cb(e);
}
} finally {
Monitor.Exit(_lock);
}
}

public T Result {
get {
if (!_complete) {
Monitor.Enter(_lock);
}
if (_success) {
return _result;
} else {
Console.WriteLine("Throwing error complete={0} success={1}", _complete, _success);
throw _error;
}
}
}

// Failing test
public void TestResultSuccess() {
var f = new Future<int>(() => 1);
var x = f.Result;
Assert.AreEqual (1, x);
}

我在 Mac OS X 10.9 上使用 Mono 3.2.3。

最佳答案

只有取得锁的线程才能退出锁。您不能在调用线程的构造函数中 Enter 它,然后在它完成时从线程池中 Exit - 线程池 worker 没有锁

并且相反:大概是创建 future 的同一个线程正在访问 getter:允许再次Enter:它是重新-参赛者。此外,您需要 Exit 的次数与 Enter 的次数相同,否则它实际上不会被释放。

基本上,我认为 Monitor 不是正确的方法。

关于c# - 监视器似乎没有锁定对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20266175/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com