2015-04-20 162 views
-1

我有以下POCO课程。我应该考虑以下代码作为线程安全吗?

public class SessionInfo 
{ 
    public int UserID { get; set; } 
    public string UserName { get; set; } 
    public string Name { get; set; } 
    public List<Role> UserRoles { get; set; } 
    public List<Permission> Permissions { get; set; } 
} 

和如下SessionService类:

public static class SessionService 
{ 
    static string userName; 
    static int userID; 
    static List<Role> RoleList; 

    public static SessionInfo SetServiceSession<T>(T service) where T : class 
    { 
     SessionInfo sessionInfo; 
     SetApiControllerSessionValue(); 
     sessionInfo = new SessionInfo { UserID = userID, UserName = userName, UserRoles = RoleList, Name = null, Permissions = null }; 
     //above statement fills the value set by SetApiControllerSessionValue into the sessionInfo object and returns. 
     return sessionInfo; 
    } 

    private static void SetApiControllerSessionValue() 
    { 
     ..... 
     ..... 
     //Here is some logic that sets the static member `userName`, `userId` and `RoleList` of `SessionService` class 
     ..... 
     ..... 
    } 
} 

现在我打电话从像下面每个API控制器的每一个动作SetServiceSession方法:

public class TestController : ApiController 
{ 

    public List<TestPOCO> Get() 
    { 
     ..... 
     ..... 
     TestService service = new TestService(uow); 
     SessionInfo = SessionService.SetManagerSession<TestService>(service); 
     ..... 
     ..... 
     ..... 
    } 

    ..... 
    ..... 
    // Same way for post, create and delete. 
    .....   
    ..... 

} 

现在,如果服务器同时处理两个请求让我们说Get和Post两个不同的会话,SessionService.SetManagerSession将并行执行。所以问题是它可能会导致无效的会话值(在两个请求中交换静态值),因为它正在并行执行?如果是,那么解决方案是什么?

也纠正我,如果我对上述代码的理解是错误的。

在此先感谢。

+0

一个静态类,它拥有一个拥有'userID'属性的静态属性,当然不是线程安全的并且存在安全风险。 – DavidG

+0

@DavidG嗯..所以我的怀疑变成了现实。你能否在这种情况下建议我可能的解决方案? –

+0

请勿使用静态类或传递所需的所有值作为参数。 – DavidG

回答

3

我应该考虑下面的代码作为线程安全吗?

不,显然不是。如果SetServiceSession同时处于多个线程中,则userName,userID等字段将被混淆。

如果是这是什么解决方案?

只有两个选项。

  1. 请勿使用共享状态。
  2. 使用正确的同步。

我更喜欢选项1.在这种情况下,您可以完全摆脱该静态成员,并使SetApiControllerSessionValue返回SessionInfo。当然,将方法重命名为GetApiControllerSessionValue

public static SessionInfo SetServiceSession<T>(T service) where T : class 
{ 
    SessionInfo sessionInfo = GetApiControllerSessionValue(); 
    //Do something with sessionInfo, if needed 
    return sessionInfo; 
} 

private static SessionInfo GetApiControllerSessionValue() 
{ 
    //Get SessionInfo here. 
    //If you need to access any other shared state here, you must need synchronization. 
} 

有关的同步原语refer this更多的信息。如果你想要我提供一个特定的答案而不是上面的通用答案,请发布你的原始代码。