如何异步使用DataAdapter.Fill()?

时间:2016-07-20 18:40:25

标签: c# winforms asynchronous datatable ado.net

我有一个DataAdapter,它在DataSet中填充了5个DataTable。

SqlDataAdapter da = new SqlDataAdapter("Select * from testTable",con);
da.Fill(ds, 0, numberOfRowsToPutInEachDataTable, "DT1");
da.Fill(ds, numberOfRowsToPutInEachDataTable , numberOfRowsToPutInEachDataTable , "DT2");
da.Fill(ds, numberOfRowsToPutInEachDataTable* 2, numberOfRowsToPutInEachDataTable, "DT3");
da.Fill(ds, numberOfRowsToPutInEachDataTable * 3, numberOfRowsToPutInEachDataTable, "DT4");
da.Fill(ds, numberOfRowsToPutInEachDataTable * 4, numberOfRowsToPutInEachDataTable, "DT5");

我的目标是获得每个

da.Fill...

同时异步运行。

我没有异步运行的经验,并且很难通过研究找到解决方案。谁能告诉我如何让这些DataAdapter.Fill()异步运行?

2 个答案:

答案 0 :(得分:2)

您可以这样使用多个Task.Run()的多个线程:

Task.Run(() =>
{
    da1.Fill(ds.Table1);
    this.Invoke(new Action(() => {dataGridView1.DataSource = ds.Table1;}));
});
Task.Run(() =>
{
    da2.Fill(ds.Table2);
    this.Invoke(new Action(() => {dataGridView2.DataSource = ds.Table2;}));
});

这样,数据将同时使用2个不同的线程加载,而不会冻结表单。

在上面的代码中,da1.Fillda2.Fill会同时调用不同的线程。由于代码执行的是与UI线程不同的线程,因此要设置DataSource的{​​{1}},您应该使用DataGridView

答案 1 :(得分:-1)

如何使用PLINQ

SqlDataAdapter da = new SqlDataAdapter("Select * from testTable", con);

IEnumerable<int> results = new string[]
{
    "DT1", "DT2", "DT3", "DT4", "DT5"
}
.AsParallel()
.Select((table, index) => da.Fill(ds, 
                          numberOfRowsToPutInEachDataTable * index, 
                          numberOfRowsToPutInEachDataTable, 
                          table));

修改

绝对不建议使用建议的解决方案。

DataSet似乎不支持并发写操作:

  

此类型对于多线程读取操作是安全的。 您必须同步任何写入操作