0

我正在编写一个 .NET 4.0 控制台应用程序

  1. 打开连接 使用数据阅读器在键列表中游标

  2. 对于每个键读取,调用 Web 服务

  3. 将 Web 服务的结果存储在数据库中

然后,我生成此进程的多个线程,以提高每秒可以处理的最大记录数。

当我的进程超过大约 30 个线程时,我收到以下错误:

System.InvalidOperationException: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.   This may have occurred because all pooled connections were in use and max pool size was reached.

是否有服务器或客户端选项可以调整以允许我从连接池中获取更多连接?

我正在调用一个 sql 2008 r2 数据库。

谢谢

4

3 回答 3

1

这听起来像是一个设计问题。数据库中的总记录数是多少?遍历阅读器会非常快。即使您有数十万行,浏览该阅读器也会很快。这是您可以采取的另一种方法:

遍历阅读器并将数据存储在对象列表中。然后以您选择的数量(例如,一次两个,一次三个等)遍历您的对象列表,并生成该数量的线程以并行调用您的 Web 服务。

这样您就不会打开与数据库的多个连接,并且您正在处理可能是真正的瓶颈(对 Web 服务的 HTTP 调用)的并行处理。

这是一个例子:

List<SomeObject> yourObjects = new List<SomeObject>();

if (yourReader.HasRows) {
    while (yourReader.Read()) {
        SomeObject foo = new SomeObject();
        foo.SomeProperty = myReader.GetInt32(0);
        yourObjects.Add(foo);
    }
}

for (int i = 0; i < yourObjects.Count; i = i + 2) {
    //Kick off your web service calls in parallel.  You will likely want to do something with the result.
    Task[] tasks = new Task[2] {
        Task.Factory.StartNew(() => yourService.MethodName(yourObjects[i].SomeProperty)),
        Task.Factory.StartNew(() => yourService.MethodName(yourObjects[i+1].SomeProperty)),
    };

    Task.WaitAll(tasks);
}

//Now do your database INSERT.
于 2012-04-27T17:40:35.043 回答
0

为您的所有请求打开一个新连接是非常低效的。如果您只是想使用相同的连接来继续请求事物,那是不可能的。您可以打开一个连接,然后SqlCommand通过该连接运行尽可能多的命令。只需保留 ONE 连接,并在所有线程完成后将其丢弃。

于 2012-04-27T17:40:59.817 回答
-1

请重新启动您将能够连接的 IIS

于 2013-11-22T13:49:36.723 回答