2014-02-13 95 views
3

我有以下代碼。對connection.OpenAsync()的調用沒有任何異常退出程序。即使是最後的調用者方法也不會被調用。程序是針對.NET45的任何想法?SqlConnection.OpenAsync()退出而不拋出異常

更新:這是與.Wait()一起使用的父代碼。當connection.OpenAsync()在下面的子方法中調用時,它在父代碼中沒有.Wait()時退出。

 static void Main(string[] args) 
     { 
      UpdateSqlDatabase updateSqlDatabase = new UpdateSqlDatabase(args); 
      updateSqlDatabase.UpdateDatabaseSchemaAsync().Wait(); 
     } 

一系列異步方法的調用之後:

public async Task<T> ExecuteQueryAsync<T>(string connectionString, string commandText, IDictionary<string, object> parameters, Func<SqlDataReader, T> rowMapFunc) 
    { 
     using (var connection = new SqlConnection(connectionString)) 
     { 
      try 
      { 
       await connection.OpenAsync(); 
      } 
      catch (Exception ex) 
      { 
      } 

      SqlCommand command = connection.CreateCommand(); 
      command.CommandType = CommandType.Text; 
      command.CommandText = commandText; 
      if (parameters != null) 
      { 
       foreach (var item in parameters) 
       { 
        command.Parameters.AddWithValue(item.Key, item.Value); 
       } 
      } 

      SqlDataReader reader = await command.ExecuteReaderAsync(); 
      T retObj = default(T); 

      while (await reader.ReadAsync()) 
      { 
       retObj = rowMapFunc(reader); 
      } 

      return retObj; 
     } 
    } 
+0

不這樣做:'趕上(例外){}',你是搬起石頭砸自己的腳。畢竟,什麼是例外細節? – Noseratio

+0

當我調試代碼永遠不會到達。我添加了這個catch來看看哪裏出了問題(不會成爲我的代碼的一部分)。本質上,當我調試執行connection.OpenAsync()只是退出程序。即控制檯應用程序只是退出而沒有任何錯誤/異常。 catch代碼塊在這段代碼中從未被擊中。 – ksj

+0

像這樣更改您的代碼:http://pastebin.com/ZmsA3k4g。在「A」,「B」,「C」,「D」行上設置斷點並在調試器下運行。什麼斷點受到打擊? – Noseratio

回答

2

所以,問題是,在代碼中,我有異步調用的鏈,但父(主)方法不是異步,並沒有等待使程序當一個子方法調用Async時退出。我添加了.Wait()從main方法(這是同步)調用異步方法,它工作正常。

謝謝!

+1

在異步鏈的根目錄中有一個'.Wait()'幾乎從來都不是正確的事情,並且經常會導致程序鎖定死鎖!要麼你應該在沒有任何異步的情況下編寫代碼,要麼在任務上調用Wait()的函數應該是async和await,而不是'.Wait()'。如果可以的話,更新你的問題並顯示你添加'.Wait()'的初始函數,我們可以幫助你找出哪個選項是正確的。 –

+0

好吧,從你添加的代碼中,你是在「不要使用異步」的一面。您正在使用控制檯應用程序,沒有理由使用異步代碼。它所做的只是增加開銷並放慢你的代碼。看看是否有'updateSqlDatabase.UpdateDatabaseSchema()'版本的函數,你應該在你的情況下使用它。 –

+0

我在原文中添加了代碼。謝謝你的幫助。 – ksj

1

msdn documentation狀態這樣的:

例外將通過返回的任務傳播。如果 連接超時時間未成功連接, 返回的任務將被標記爲發生故障並出現異常。 實現返回一個任務,但不會阻塞 連接池和非連接池的調用線程。

所以,正確使用connection.OpenAsync()寧可將是這個樣子

using(var connection = new SqlConnection(connectionString)) 
{ 
    var connectionTask = connection.OpenAsync(); 
    // other code goes here 
    Task.WaitAll(connectionTask); //make sure the task is completed 
    if(connectionTask.IsFaulted) // in case of failure 
    { 
     throw new Exception("Connection failure", connectionTask.Exception); 
    } 
    // rest of the code 
}