这段代码是线程安全的吗?如何使其线程安全?

时间:2009-08-11 04:54:19

标签: c# .net wcf multithreading thread-safety

我有一个带有安全类的WCF服务,用于获取调用用户的某些属性。但是在线程安全性方面我非常糟糕 - 到目前为止,我并不需要做太多的事情,而且只对多线程问题有一个基本的理论上的理解。

给出以下功能:

public class SecurityService
{
    public static Guid GetCurrentUserID()
    {
        if (Thread.CurrentPrincipal is MyCustomPrincipal)
        {
            MyCustomIdentity identity = null;
            MyCustomPrincipal principal = (MyCustomPrincipal)Thread.CurrentPrincipal;
            if (principal != null)
            {
                identity = (MyCustomIdentity)principal.Identity;
            }

            if (identity != null)
            {
                return identity.UUID;
            }
        }
        return Guid.Empty;
    }
}

如果从2个不同的线程同时调用该方法,是否有可能出现问题?在我的噩梦中,如果这些方法出错,我会看到可怕的后果,例如有人意外地获取其他人的数据或突然变成系统管理员。一位同事(他也不是专家,但他比我好)认为它可能没问题,因为那里没有真正的共享资源。

或者这个将访问数据库的人可能会出错吗?

    public static User GetCurrentUser()
    {
        var uuid = GetCurrentUserID();
        if (uuid != null)
        {
            var rUser = new UserRepository();
            return rUser.GetByID(uuid);
        }
        return null;
    }

关于线程的原理有很多讨论,但是当涉及到实际应用它时,我倾向于陷入困境并且知道何时应用它。任何帮助表示赞赏。

如果不清楚,我可以更详细地解释这些功能的背景/目的。

编辑: rUser.GetByID()函数基本上调用一个使用NHibernate查找数据库的存储库。所以我想这里的数据库是一个“共享资源”,但实际上并没有被锁定或修改过这个操作...在这种情况下我猜它没关系......?

2 个答案:

答案 0 :(得分:12)

从我看到的,第一个例子只访问线程本地存储和基于堆栈的变量,而第二个例子只访问基于堆栈的变量。

两者都应该是线程安全的。

我无法判断GetByID是否是线程安全的。查看它是否访问任何共享/静态资源。如果确实如此,如果没有一些额外的代码来保护这些资源,它就不是线程安全的。

答案 1 :(得分:3)

上面的代码不包含更改全局状态的任何代码,因此您可以相当确定多个同时线程调用它不会成为问题。安全主体信息与每个线程相关联,因此也没有问题。