2008-12-02 148 views
2

我將只讀數據庫操作拆分爲多個塊(每個塊讀取大量數據的子集,分析它並將結果寫入磁盤文件)。使用多線程和連接池時避免連接超時

每個數據塊上執行一個新的.NET線程選擇(成一個DataTable)(使用委託和的BeginInvoke)

有數據的多個子集以外還有池中可用連接,所以當我在第一個連接請求釋放之前,連接請求排隊等待,直到連接超時到期,然後出現超時異常。

我該如何:A)當連接池中的連接全部被使用時,禁止超時連接異常,或者B)在我甚至要求另一個連接之前檢測到它們全部被使用,所以我可以等到一個在詢問之前是否可用?

回答

1

兩個解決方案:

A)用幾天超時配置連接池。這將阻止掛起的任務,直到返回連接。缺點:任務掛起時這不起作用。

B)使用線程池和工作隊列。線程池必須具有與連接池相同的大小(即每個線程一個連接)。將所有工作放在隊列中,並讓任務從隊列中獲取工作項,直到隊列爲空。

的溶液B僞代碼:

public class Setup 
    connPool = createConnectionPool(100); 
    queue = createWorkQueue(); 
    putAllWorkItemsInQueue(queue); 
    for (int i=0; i<connPool.size(); i++) { 
     t = new WorkerThread(queue) 
     list.add(t); 
     t.start(); 
    } 
    while (queue.size() != 0) { 
     Thread.sleep(1000); 
    } 
    for (thread in list) { 
     thread.interrupt(); 
    } 

public class WorkerThread 
    run() { 
     while (true) { 
      try { 
       workUnit = queue.get(); // This blocks 
       process(workUnit); 
      } catch (InterruptedException e) { 
       break; 
      } 
     } 
    } 
+0

與選項B,此線程池設置爲100個線程的最大(因爲conections池設置爲100),然後,在我的代碼,我調用BeginInvoke (),當所有100個線程都在使用時,我掛起,直到以前使用的線程完成並釋放回我的線程池? – 2008-12-02 15:13:51