2009-02-06 121 views
0

我正在设计一个高度并发的CCR应用程序,在这个应用程序中,我不会阻止或发送睡眠线程。SQLConnection Pooling - 处理InvalidOperationExceptions

我打的SQLConnection池的问题 - 试图调用SqlConnection.Open

我有可能重试满手的时候,特别是越来越InvalidOperationExceptions,但这不是真正解决问题。

对我来说,理想的解决办法是定期重新检查可用性被捆绑

任何想法一个线程,不需要连接的方法?

[更新] 这里是一个相关的问题/溶液张贴在another forum

该解决方案需要手动管理的连接池。我宁愿有一个更具动态性的解决方案,即在需要时踢人

+0

代码示例请? – 2009-02-06 03:09:08

+0

我认为这是一个普遍的CCR问题,如果您已经熟悉CCR – 2009-02-06 03:19:31

回答

1

哈利,我也碰到过这个,同时还使用了CCR。我的经验是,通过完全分离我的调度程序线程,阻止任何I/O,我可以比SqlConnection池能够处理的更快地消耗和处理工作项目。一旦达到最大游泳池限制,我遇到了你所看到的那种错误。

最简单的解决方案是预先分配一些非池异步SqlConnection对象并将它们发布到一些中央端口<SqlConnection>对象。然后,当你需要执行一个命令,一个迭代器内这样做的东西是这样的:

public IEnumerator<ITask> Execute(SqlCommand someCmd) 
{ 
    // Assume that 'connPort' has been posted with some open 
    // connection objects. 
    try 
    { 
     // Wait for a connection to become available and assign 
     // it to the command. 
     yield return connPort.Receive(item => someCmd.Connection = item); 

     // Wait for the async command to complete. 
     var iarPort = new Port<IAsyncResult>(); 
     var iar = someCmd.BeginExecuteNonQuery(iarPort.Post, null); 
     yield return iarPort.Receive(); 

     // Process the response. 
     var rc = someCmd.EndExecuteNonQuery(iar); 
     // ... 
    } 
    finally 
    { 
     // Put the connection back in the 'connPort' pool 
     // when we're done. 
     if (someCmd.Connection != null) 
      connPort.Post(someCmd.Connection); 
    } 
} 

有关使用CCR中的好处是,它是微不足道的下面的功能添加到这个基本的代码。

  1. 超时 - 只需进行初始接收(对于可用的连接),使用超时端口的“选择”。
  2. 动态调整池大小。要增加池的大小,只需将一个新的打开的SqlConnection发布到'connPort'。要减小池的大小,请在connPort上产生一个接收,然后关闭接收到的连接并将其丢弃。
0

是的,连接保持打开并且不在连接池中。在上面的例子中,端口池。