C#监视奇怪的行为

时间:2014-11-26 14:23:20

标签: c# synchronization thread-safety monitor

也许你可以告诉我这里我做错了什么: 我有一个同步对象,我正在使用Monitor.TryEnter来获取该对象的锁定,但是当我尝试再次获取它时(使用Monitor.TryEnter),我仍然设法得到它。 样品:

public class SafeDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IXmlSerializable
{
    private readonly object syncRoot = new object();
    private Dictionary<TKey, TValue> myDict = new Dictionary<TKey, TValue>();
    private const int monitorEnterTimeout = 5000;       // Timeout for Monitor (5 sec)
    private string dictionaryTitle;



    /* CODE */
    public void Add(TKey key, TValue value)
    {
        bool isLockTaken = false;

        try
        {
            // Acquire the lock:
            Monitor.TryEnter(syncRoot, monitorEnterTimeout, ref isLockTaken);
            if (!isLockTaken)
            {
                Log(@"Failed to Enter a monitor.");
                return;
            }

            // Add to the dictionary:
            myDict.Add(key, value);
            Backup(); // We haven't released the lock yet!
        }
        catch (System.Exception ex)
        {
            Log(String.Format("Error adding to the dictionary: {0}", ex.ToString()));
        }
        finally
        {
            if (isLockTaken)
            {
                Monitor.Exit(syncRoot);
            }
        }
    }
    private void backup()
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        bool isLockTaken = false;
       /* CODE... */

        try
        {
            // #####  We should not be able to take the key and enter the monitor:
            Monitor.TryEnter(syncRoot, monitorEnterTimeout, ref isLockTaken);
            if (!isLockTaken)
            {
                Log(@"Failed to Enter a monitor.");
                return;
            }
            // #####  YET we arrive here with isLockTaken = true
            /* CODE */
        }
        catch (System.Exception ex)
        {
            Log(String.Format("Error Serializing the dictionary: {0}", ex.ToString()));
        }
        finally
        {
            if (isLockTaken)    
            {
                Monitor.Exit(syncRoot);
            }
        }
    }

我也尝试使用调试器的“即时窗口”并尝试重新进入Monitor部分(重置布尔值后),每次都成功。我究竟做错了什么? 感谢

0 个答案:

没有答案