2012-09-26 12 views
5

का उपयोग कर डेटाटेबल लौटाएं मेरे पास एक तरीका है जो एक डेटाटेबल देता है। मैंने सोचा था कि .NET 4.0 का उपयोग करके मैं केवल एसिंक तर्क और डेटा लौटा सकता हूं। लेकिन यह कोड शून्य डेटाटेबल ऑब्जेक्ट देता है। कोई भी विचार इस कोड के साथ क्या गलत है।async .net 4.0

public DataTable GetData(string sql, string connectionName) 
{ 
    DataTable dt = (DataTable)GetDataAsync(sql, connectionName).AsyncState; 
    return dt; 
} 

private async Task<DataTable> GetDataAsync(string sql, string connectionName) 
{ 
    return await TaskEx.Run(() => { return FillData(sql, connectionName); }); 
} 

private DataTable FillData(string sql, string connectionName) 
{ 
    SqlConnection conn = _connections.Where(w => w.ConnectionName == connectionName).Single().Connection; 
    SqlDataAdapter adp = new SqlDataAdapter(sql, conn); 
    DataSet ds = new DataSet(); 

    adp.Fill(ds); 

    return ds.Tables[0]; 
} 
+0

आप .NET 4.0 या C# 4 के साथ 'async' /' await' का उपयोग नहीं कर सकते हैं। यह सी # 5 में एक नई सुविधा है, और .NET 4.5 में प्रकारों पर निर्भर करता है। –

+4

जॉन - चूंकि वह TaskEx.Run का उपयोग कर रहा है, मुझे लगता है कि वह एसिंक लक्ष्यीकरण पैक का उपयोग कर रहा है, जो आपको 4.0 को लक्षित करने और एसिंक/await –

उत्तर

9

सबसे पहले, आपको .NET 4 के साथ async/await या उपयोग नहीं कर सकते सी # 4. यह सी # 5. थे CTPs जो .NET 4 के शीर्ष पर स्थापित में एक नई सुविधा है, लेकिन वहाँ निश्चित कीड़े हैं उन सीटीपी में - उनका उपयोग न करें। आपको .NET 4.5 के पूर्ण रिलीज़ संस्करण का उपयोग करना चाहिए, जिसमें सी # 5 कंपाइलर शामिल है। (यह सब विजुअल स्टूडियो 2012 में है।)

दूसरा, आप कार्य की गलत संपत्ति का उपयोग कर रहे हैं, क्योंकि कुओंग ले ने दिखाया था। Result संपत्ति Task<T> के परिणामस्वरूप आप कैसे प्राप्त करते हैं।

तीसरा, Result संपत्ति का उपयोग करने के लिए परिवर्तन करने के बाद, आप तालिका को लाने के लिए अवरुद्ध कर देंगे - इसे व्यर्थ बनाते हैं। यह:

public DataTable GetData(string sql, string connectionName) 
{ 
    return FillData(sql, connectionName); 
} 

आप एक काम शुरू करने के लिए और तुरंत उस पर इंतजार जा रहे हैं, आप के साथ-साथ बस विधि तुल्यकालिक कॉल कर सकते हैं:

public DataTable GetData(string sql, string connectionName) 
{ 
    DataTable dt = (DataTable)GetDataAsync(sql, connectionName).Result; 
    return dt; 
} 

... बड़े पैमाने पर करने के लिए बराबर है।

+0

का उपयोग करने की सुविधा देता है ठीक है तो मैं इसे जॉन में मदद कर सकता हूं .net 3.5 में यह कैसे कर सकता हूं? ? – Malcolm

+0

मैं केवल एसिंक के लिए 4.0 का उपयोग करने जा रहा था इसलिए मैं अब इसका उपयोग नहीं करूँगा। – Malcolm

+0

@ मैल्कम: किसी भी कारण से आप 4.5 का उपयोग नहीं करना चाहते हैं? –

2

यदि आप async कोड का उपयोग करना चाहते हैं, तो don't block on it। साथ ही, सुनिश्चित करें कि आप Async Targeting Pack का उपयोग कर रहे हैं और एक Async CTP नहीं।

private async Task<DataTable> GetDataAsync(string sql, string connectionName) 
{ 
    return await TaskEx.Run(() => { return FillData(sql, connectionName); }); 
} 

private async GetAndProcessDataAsync() 
{ 
    DataTable table = await GetDataAsync("my sql", "my connection name"); 
    ProcessData(table); 
} 
8

मेरा अपना स्रोत कोड।

public static async Task<DataTable> GetDataTableAsync(this System.Data.Common.DbCommand command, CancellationToken cancellationToken, string tableName = null) 
    { 
     TaskCompletionSource<DataTable> source = new TaskCompletionSource<DataTable>(); 
     var resultTable = new DataTable(tableName ?? command.CommandText); 
     DbDataReader dataReader = null; 

     if (cancellationToken.IsCancellationRequested == true) 
     { 
      source.SetCanceled(); 

      await source.Task; 
     } 

     try 
     { 
      await command.Connection.OpenAsync(); 
      dataReader = await command.ExecuteReaderAsync(CommandBehavior.Default); 
      resultTable.Load(dataReader); 
      source.SetResult(resultTable); 
     } 
     catch (Exception ex) 
     { 
      source.SetException(ex); 
     } 
     finally 
     { 
      if (dataReader != null) 
       dataReader.Close(); 

      command.Connection.Close(); 
     } 

     return resultTable; 
    } 
+0

अच्छा, हालांकि आपको ओपनएसिंक और एक्सीक्यूट रीडर एसिंक तरीकों से अपने रद्दीकरण टोकन को भी पास करना चाहिए ताकि रद्द करने से इन्हें –

+0

रोक दिया जा सके, वास्तव में समाधान प्रदान करने के लिए धन्यवाद। पास करने के लिए रद्दीकरण टोकन कहां मिलते हैं? – toddmo

+0

आप निपटान पर आपके लिए सबकुछ बंद करने के लिए 'उपयोग' पैटर्न का उपयोग कर सकते हैं। – toddmo