Saya mengirimkan serangkaian pernyataan select
(kueri - ribuan di antaranya) ke satu database secara sinkron dan mendapatkan kembali satu DataTable
per kueri (Catatan: Program ini sedemikian rupa sehingga memiliki pengetahuan tentang skema DB yang dipindai hanya pada saat dijalankan. , maka penggunaan DataTables
). Program ini berjalan pada mesin klien dan terhubung ke DB pada mesin jarak jauh. Dibutuhkan waktu lama untuk menjalankan begitu banyak pertanyaan. Jadi, dengan asumsi bahwa menjalankannya secara asinkron atau paralel akan mempercepat, saya sedang menjajaki TPL Dataflow (TDF)
. Saya ingin menggunakan perpustakaan TDF
karena tampaknya menangani semua kekhawatiran terkait penulisan kode multi-utas yang seharusnya dilakukan dengan tangan.
Kode yang ditampilkan didasarkan pada http://blog.i3arnon.com/2016/05/23/tpl-dataflow/. Minimal dan hanya untuk membantu saya memahami pengoperasian dasar TDF
. Perlu diketahui bahwa saya telah membaca banyak blog dan mengkodekan banyak iterasi untuk mencoba memecahkan masalah ini.
Meskipun demikian, dengan iterasi saat ini, saya memiliki satu masalah dan pertanyaan:
Masalah
Kode ini berada di dalam metode button click
(Menggunakan UI, pengguna memilih mesin, instance sql, dan database, lalu memulai pemindaian). Dua baris dengan operator await
mengembalikan kesalahan pada waktu pembuatan: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'
. Saya tidak dapat mengubah tipe pengembalian metode klik tombol. Apakah saya perlu mengisolasi metode button click
dari kode async-await
?
Pertanyaan
Meskipun saya telah menemukan tulisan beau-coup yang menjelaskan dasar-dasar TDF
, saya tidak dapat menemukan contoh bagaimana mendapatkan output yang dihasilkan oleh setiap pemanggilan TransformBlock
(yaitu, DataTable
). Meskipun saya ingin mengirimkan pertanyaan async
, saya perlu memblokir sampai semua pertanyaan yang dikirimkan ke TransformBlock
selesai. Bagaimana cara mendapatkan rangkaian DataTable
s yang dihasilkan oleh TransformBlock
dan memblokir hingga semua kueri selesai?
Catatan: Saya mengakui bahwa saya hanya memiliki satu blok sekarang. Minimal, saya akan menambahkan blok pembatalan dan saya juga perlu/ingin menggunakan TPL.
private async Task ToolStripButtonStart_Click(object sender, EventArgs e)
{
UserInput userInput = new UserInput
{
MachineName = "gat-admin",
InstanceName = "",
DbName = "AdventureWorks2014",
};
DataAccessLayer dataAccessLayer = new DataAccessLayer(userInput.MachineName, userInput.InstanceName);
//CreateTableQueryList gets a list of all tables from the DB and returns a list of
// select statements, one per table, e.g., SELECT * from [schemaname].[tablename]
IList<String> tableQueryList = CreateTableQueryList(userInput);
// Define a block that accepts a select statement and returns a DataTable of results
// where each returned record is: schemaname + tablename + columnname + column datatype + field data
// e.g., if the select query returns one record with 5 columns, then a datatable with 5
// records (one per field) will come back
var transformBlock_SubmitTableQuery = new TransformBlock<String, Task<DataTable>>(
async tableQuery => await dataAccessLayer._SubmitSelectStatement(tableQuery),
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 2,
});
// Add items to the block and start processing
foreach (String tableQuery in tableQueryList)
{
await transformBlock_SubmitTableQuery.SendAsync(tableQuery);
}
// Enable the Cancel button and disable the Start button.
toolStripButtonStart.Enabled = false;
toolStripButtonStop.Enabled = true;
//shut down the block (no more inputs or outputs)
transformBlock_SubmitTableQuery.Complete();
//await the completion of the task that procduces the output DataTable
await transformBlock_SubmitTableQuery.Completion;
}
public async Task<DataTable> _SubmitSelectStatement(string queryString )
{
try
{
.
.
await Task.Run(() => sqlDataAdapter.Fill(dt));
// process dt into the output DataTable I need
return outputDt;
}
catch
{
throw;
}
}