我应该考虑将代码作为线程安全吗?

时间:2015-04-20 09:36:12

标签: c# asp.net-web-api

我有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将并行执行。所以问题是它是否会导致无效的会话值(在两个请求中交换静态值),因为它是并行执行的?如果是,那么解决方案是什么?

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

提前致谢。

1 个答案:

答案 0 :(得分:3)

  

我应该考虑将代码作为线程安全吗?

不,显然不是。如果SetServiceSession同时位于多个帖子中,userNameuserID等字段将会混乱。

  

如果是,那解决方法是什么?

只有两种选择。

  1. 不要使用共享状态。
  2. 使用正确的同步。
  3. 我更喜欢选项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的更多信息。如果您希望我提供一个特定的答案,而不是上面的通用答案,请发布原始代码。