我有一个用C#编写的web应用程序,它使用用C++编写的外部dll。客户端(web浏览器)和web应用程序之间的通信是使用SignalR完成的。对于web应用程序和dll之间的通信,我使用一个类,并为每个连接的客户端创建这个类的实例。这个类的实例存储在静态列表中-它是在请求之间共享的。
当发出请求时,我从列表中获取一个连接器(用于与dll通信的类),然后调用一个方法,该方法可以在0.1秒到3秒之间进行任何时间。
除此之外,我还有一项每分钟都会触发的工作(使用Hangfire),它循环遍历列表,并处理在一定时间内处于不活动状态的连接器。配置连接器也可能需要大约1或2秒。
由于应用程序是多线程的,所以我在连接器类和处理连接器的作业之间使用共享锁。使用锁,我避免在获取连接器和调用方法之间设置连接器。
在“伪代码”中,这看起来是:
object globalLock = new object();
-- signalr hub method
public void HubMethod(string sessionId, string param) {
lock (globalLock) {
DllConnector connector = GetConnector(sessionId);
connector.CallMethod(param);
}
}
-- hangfire job
public void KillInactive() {
lock (globalLock) {
foreach (DllConnector connector in listOfConnectors) {
if (connector.IsInactive()) {
listOfConnectors.Remove(connector);
connector.Dispose();
}
}
}
}问题:
因为我期待“大量”并发客户端(请求),我担心这不会扩展-请求和作业将变得没有反应。如何避免这种情况--尽量减少等待锁的时间,并避免在获取和调用方法之间设置连接器。有什么模式吗?
发布于 2015-11-29 01:32:49
这些事情通常是用线程池来完成的。参见System.Threading.ThreadPool和read MSDN:如何:使用线程池
此外,在多线程环境中共享数据的现代方法是避免使用锁,而是使用消息传递。这导致了系统的可测试性,并且一旦知道它们能工作,它们就会继续工作,而不会因为罕见的时间问题而出现令人讨厌的意外。
注意:在一个listOfConnectors.Remove( x );中调用foreach( var x in listOfConnectors )会引发一个‘集合被修改’的异常。
https://softwareengineering.stackexchange.com/questions/303798
复制相似问题