2014-08-28 8 views
12

Dato il seguente codice, ho alcune domande su best practice:Qual è la procedura migliore per riempire un DataSet o DataTable in modo asincrono in ASP.NET?

string connectionString = @"Server=(local)\sqlexpress; Database=master; Integrated Security=true;"; 

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    using (SqlDataAdapter dataAdapter = new SqlDataAdapter("select * from information_schema.columns", connection)) 
    { 
     await connection.OpenAsync(); 

     DataTable dataTable = new DataTable(); 
     await Task.Run(() => dataAdapter.Fill(dataTable)); 
     return dataTable; 
    } 
} 

che ho visto diversi esempi che avvolgono l'intero blocco di codice in una chiamata Task.Run(), ma io non sono certo se è meglio che chiamare Task.Run() solo per il metodo DataAdapter.Fill(), che si sente più flessibile e specifico (solo usando Attendere nelle attività asincrone).

L'approccio di chiamare Task.Run() sul metodo Fill() è migliore del wrapping dell'intero blocco di codice?

C'è qualche effetto collaterale negativo nel chiamare Fill() in Task.Run()? Sto pensando a qualcosa sulla falsariga di perdere stack di chiamate e/o informazioni di eccezione se Fill() ha un errore.

C'è un modo migliore per scrivere questo in ASP.NET?

+1

Perché non inserire * tutto * di quel codice all'interno di un metodo asincrono? Cioè, sposta l'attività per comprendere l'intero ciclo di vita della connessione SQL, compreso il riempimento del DataTable. – user2864740

+1

È questo ASP.NET o GUI? – usr

+0

@usr, stavo assumendo ASP.NET; c'è una grande differenza qui? –

risposta

1

In ASP.NET non è quasi mai possibile utilizzare Task.Run. Cosa esattamente migliorerebbe? Introduce solo un sovraccarico.

Detto questo, Fill eseguirà IO (svuotamento del lettore di dati) in modo che sia possibile chiamarlo in modo asincrono. Sfortunatamente, non esiste una versione asincrona di questo metodo.

Se si desidera utilizzare l'IO asincrono (which is questionable for database access) è necessario trovare un'alternativa. Forse Entity Framework async o raw ADO.NET può aiutarti.

0

Hai provato a utilizzare un DataReader e il nuovo ExecuteReaderAsync? Quello che ricordo è che SqlDataAdapter utilizza già un DataReader internamente senza async. Si consiglia inoltre di ignorare del tutto un DataTable se possibile per ridurre alcuni costi generali.

Per set di risultati di piccole dimensioni che cambiano molto raramente le colonne dello schema di query, è possibile che lo si memorizzi nel server Web in uno dei molti modi. Per quanto riguarda le modifiche allo schema, potresti persino creare un semplice trigger DDL per aggiornare una tabella a riga singola con un campo data/ora per informarti che è stata apportata una modifica, quindi eseguire la query solo quando necessario. Un'altra opzione è CHECKSUM_AGG per le tabelle diverse dalle tabelle dello schema.