这是C#中锁的推荐用法吗?

时间:2014-01-07 19:48:42

标签: c# asp.net-mvc locking

查看以下CRUD代码,我想知道是否真的有必要使用锁,如果它们可以简单地省略:

    private static readonly object Lock = new object();

    /// <summary>
    /// Returns all contacts in the list.
    /// GET /Contacts/ (Content-Type:application/json)
    /// </summary>
    [ActionName("Index"), AcceptVerbs(HttpVerbs.Get), IsAjaxRequest(true)]
    public ActionResult GetAll()
    {
        lock (Lock)
        {
            return new JsonWithStatusCodeResult(HttpStatusCode.OK, Contacts);
        }
    }

    /// <summary>
    /// Returns the contact with the provided ID.
    /// Get /Contacts/{id}
    /// </summary>
    [ActionName("Item"), AcceptVerbs(HttpVerbs.Get)]
    public ActionResult GetById(Guid id)
    {
        lock (Lock)
        {
            var index = Contacts.FindIndex(x => x.Id == id);
            if (index < 0)
            {
                ModelState.Clear();
                ModelState.AddModelError("Id", "The provided ID does not exist in the collection");
                return InvalidModelStateFilterAttribute.GetErrorResult(HttpStatusCode.NotFound, ModelState);
            }

            return new JsonWithStatusCodeResult(HttpStatusCode.OK, Contacts[index]);
        }
    }

仅供参考 - 这是我正在查看的项目的代码,并想知道在这种情况下是否有合理的理由使用锁。

感谢。

1 个答案:

答案 0 :(得分:0)

任何局部变量都不需要锁定 - 如果您正在创建类型的新本地实例,那么除非您专门将它们传递给其他线程,否则该变量不会被任何其他线程共享。

修改:正如Michael Gunther所指出的那样,Contacts方法错过了GetAll() - 就像使用GetByID()一样,如果ContactsGetByID()一个静态对象,或者如果它以某种方式在线程之间传递,它需要锁定,否则它不会。

您的Contacts可能需要一些锁定,但如果不知道所有使用的对象,很难说。 Contacts似乎是一个全局变量或成员变量,但锁定的需要取决于它是否是静态的,或者它是否被传递给其他线程。你的代码提取很难说。 {{1}}是一个全局/静态看起来非常可疑 - 但是在ASP.NET应用程序中很少需要一个真正的全局 - 大多数全局数据应该存储在数据库中或者它应该是不变的(在这种情况下你在静态构造函数中初始化它然后只能在之后读取它,因此不需要锁定。)