public PooledSocket Acquire()
{
if (log.IsDebugEnabled)
log.Debug("Acquiring stream from pool.");
if (!this.IsAlive)
{
if (log.IsDebugEnabled)
log.Debug("Pool is dead, returning null.");
return null;
}
// every release signals the event, so even if the pool becomes full in the meantime
// the WaitOne will succeed, and more items will be in the pool than allowed,
// so reset the event when an item is inserted
this.itemReleasedEvent.Reset();--------------这边reset有意义吗?有兄弟知道吗?
PooledSocket retval = null;
// do we have free items?
if (this.freeItems.Dequeue(out retval))
{
try
{
retval.Reset();
if (log.IsDebugEnabled)
log.Debug("Socket was reset. " + retval.InstanceId);
Interlocked.Increment(ref this.workingCount);
return retval;
}
catch (Exception e)
{
log.Error("Failed to reset an acquired socket.", e);
this.MarkAsDead();
return null;
}
}
else
{
// free item pool is empty
if (log.IsDebugEnabled)
log.Debug("Could not get a socket from the pool.");
// we are not allowed to create more, so wait for an item to be released back into the pool
if (this.workingCount >= this.maxItems)
{
if (log.IsDebugEnabled)
log.Debug("Pool is full, wait for a release.");
// wait on the event
if (!itemReleasedEvent.WaitOne(this.connectionTimeout,true))
{
if (log.IsDebugEnabled)
log.Debug("Pool is still full, timeouting.");
// everyone is working
throw new TimeoutException();
}----------------------当获取信号量的时候...代码会接着往下走,也就是说,并不是从已有的队列中去取一个socket出来..而又去createsocket一个出来...不知道是写的太烂,还是我没理解清楚?
}
if (log.IsDebugEnabled)
log.Debug("Creating a new item.");
try
{
// okay, create the new item
retval = this.CreateSocket();
Interlocked.Increment(ref this.workingCount);
}
catch (Exception e)
{
log.Error("Failed to create socket.", e);
this.MarkAsDead();
return null;
}
}
if (log.IsDebugEnabled)
log.Debug("Done.");
return retval;
}
没有看出来问题在哪里,你认为是哪里有问题呢?
你的代码写了那么多调试用的语句,看着有些乱,整个代码好像是从socket池里取一个socket。
1、先看socket池是不是处于活动状态,如果socket池已经死了就返回null
2、this.itemReleasedEvent.Reset();看样子是重置一个socket释放的信号量,后面会wait它,你可以找一下什么地方set的,应该是一个不用的socket释放的时候set,这样后面发现池已满的时候可以等待一段时间,等有别的socket释放。
3、然后就从空闲的socket里取出一个返回。
4、如果取不出来说明空闲socket队列是空的,那么判断已有的socket有没有达到池的上线,如没有达到就创建一个新的socket返回。
5、如果已有的socket已经达到池的上线,就等待itemReleasedEvent信号量一定的时间,如果在这段时间内有不用的Socket释放,就还创建一个新的,否则就抛出超时的错误。
整个逻辑你简化代码后就看的清楚了
public PooledSocket Acquire()
{
if (!this.IsAlive)
{
return null;
}
this.itemReleasedEvent.Reset();
PooledSocket retval = null;
if (this.freeItems.Dequeue(out retval))
{
try
{
retval.Reset();
Interlocked.Increment(ref this.workingCount);
return retval;
}
catch (Exception e)
{
this.MarkAsDead();
return null;
}
}
else
{
if (this.workingCount >= this.maxItems)
{
if (!itemReleasedEvent.WaitOne(this.connectionTimeout,true))
{
throw new TimeoutException();
}
}
try
{
retval = this.CreateSocket();
Interlocked.Increment(ref this.workingCount);
}
catch (Exception e)
{
return null;
}
}
return retval;
}
你可能感觉等到有空闲的socket释放了,为什么还创建一个新的socket,那么它的池不就没用了吗,其实一个已经释放的socket是没法直接的重用,因为一个socket有local endpoint和remote endpoint,要把一个已经连接到a主机的socket又要连到b主机得用反射清空一些东西才行,具体我也不太清楚,你可以查下资料,一般做socket server的时候才会考虑socket池,你可以查下winsock的acceptex函数,他可以让一个socket重用,我以前的帖子贴过用法。其实它这个池在空闲socket池没空的时候还是有作用的,对吧。