2011-03-26 30 views
0

我通过使用PokiIn库将通知推送到客户端,在我的MVC Web应用程序中实现COMET。如何通过其方法同步对类的私有静态字段的访问?

每当客户端连接,ClientID的是在CometWorker类的OnClientConnected事件可供选择:

public static Dictionary<int, string> clientsList 
          = new Dictionary<int, string>(); 
public static string clientId = ""; 
static void OnClientConnected(string clientId, 
             ref Dictionary<string, object> list) 
{ 
     BaseController.clientId = clientId; 
} 

我分配在处理程序接收控制器的静态客户端Id的ClientID的。然后当处理器的动作被调用时,我这个clientid映射到的身份登录的用户: -

public ActionResult Handler() 
     { 
      if (User.Identity.IsAuthenticated) 
      { 
       if (clientsList.Keys.Contains(currentUser.UserId)) 
        clientsList[currentUser.UserId] = clientId; 
       else 
        clientsList.Add(currentUser.UserId, clientId); 
      } 
      return View(); 
     } 

由于多个请求将由不同的线程在服务器上提供服务,每次都会访问静态客户端Id在这两种方法。

如何同步其访问权限,以便在两种方法(OnClientConnected和Handler)中直接完成一个请求,另一个请求等待它?

请告诉我,如果我的问题不清楚。我会尽力进一步改进。

+0

可能重复(http://stackoverflow.com/questions/5441657/how-can-i-lock-a-private-static-field-of-a-class-in-one-static-method-and-then-re) – 2011-03-26 13:38:20

回答

2

将clientid存储在用户的会话中,而不是存储在控制器的静态变量中。它需要与用户关联的数据而不是整个应用程序。或者更好的是,在客户端连接时解析名称/ ID查找。

+0

我无法在静态OnClientConnected事件中访问用户会话,这就是为什么我将其分配给静态字段,然后在Action Method中使用它。 – teenup 2011-03-26 13:08:09

+0

@Puneet - 甚至没有通过HttpContext.Current?它应该是可用的,因为“事件”显然与请求相关联。 – tvanfosson 2011-03-26 13:11:00

+0

不,我无法访问HttpContext.Current,我认为它也是正确的,因为静态方法不能访问实例方法,而Current与一个实例相关联。我需要一种方法来锁定第一个事件方法中的ClientId并保持锁定,直到第二个Handler方法执行并将ClientId映射到UserId。直到其他人应该等待。 – teenup 2011-03-26 13:16:30

0

我认为你应该使用lock(clientsList){},每当你想更新你的字典

的[我怎么能锁定一个类的私有静态字段在一个静态方法,然后在其他一些实例方法释放?]
+0

您不应该锁定公共对象,因为您的代码的其他部分可以执行相同的操作。请参阅:http://stackoverflow.com/questions/251391/why-is-lockthis-bad – 2011-03-26 17:52:58