2013-07-10 39 views
2

我有這行代碼一個嚴重的問題:如何處理呼叫這是容易掛在當前線程

new OdbcConnection(builder.ConnectionString)

我們的客戶,每天晚上把他的DB2數據庫停機備份,並有時這會導致我們的代碼掛在這行代碼中。即使在等待一個小時後仍然卡住。不幸的是,這個錯誤不能隨意複製,只會隨機出現幾天。

有像這樣的問題KB article at Microsoft但這種解決方法是不適用的,因爲我們的MDAC的版本應該是新的。

我發現沒有其他手段來解決這個問題,所以我要開始一個新的線程,讓它嘗試創建可在超時之後被殺害的對象。 我可以使用任務,但只能使用取消標記取消任務,因爲任務由其中一行代碼掛起或不掛起而不能評估。

在尋找如何中止任務,大家說,你不能中止任務,你不應該使用Thread.Abort的。

然而,在這種情況下,我沒有看到任何其他的可能性莫過於此。任何人都可以提出一個更好的方式來處理這個掛起的代碼?

+0

如何清理一下就可以了,你實例化進程的另一個副本,並立即強行終止當前與Environment.Exit?新的實例將運行起來,並找到數據庫不可用,可能會定期重試,直到數據庫確實出現,然後正常運行(直到下一次掛斷:)。 –

+0

這只是掛起的許多工作之一。所以我不能隨意重啓服務。而且我仍然需要一個控制實例。 – Zebi

回答

-1

好像只是開始一個新的線程,因爲那裏是掛起代碼將只會加重你的問題的條件,它肯定不是一個線程的目的。我會建議一個Try/Catch/Finally塊來防止代碼掛起。

+1

Try/Catch/Finally可能根本沒有幫助。如果呼叫阻塞,Catch/Finally將不會被執行。 –

+0

這是正確的嘗試/捕獲將無法正常工作。 – Zebi

1

所以在這裏不建議,我拿到這個問題是:

private OdbcConnection ResolveConnection(OdbcConnectionStringBuilder connectionString) 
{ 
    if (!_connections.ContainsKey(connectionString.Dsn)) 
    { 
     OdbcConnection connection = null; 

     var newOdbcConnectionTimeout = TimeSpan.FromSeconds(30); 
     var evt = new ManualResetEvent(false); 

     var connectionThread = new Thread(() => 
      { 
       try 
       { 
        connection = new OdbcConnection(connectionString.ConnectionString); 
       } 
       finally 
       { 
        evt.Set(); 
       } 
      }); 
     connectionThread.Start(); 
     var isOk = evt.WaitOne(newOdbcConnectionTimeout); 

     if (!isOk || connection == null) 
     { 
      connectionThread.Abort(); 
      const string messageFormat = "Timeout of {0} reached while creating OdbcConnection to {1}."; 
      throw new InvalidOperationException(string.Format(messageFormat, newOdbcConnectionTimeout, connectionString)); 
     } 

     _connections.Add(connectionString.Dsn, connection); 
    } 

    return _connections[connectionString.Dsn]; 
} 
+0

這是如何爲你工作的? –

+0

對不起,我不記得了。這是4年前:( – Zebi

相關問題