我开始探索异步并等待来自c#5.0的关键字,所以我使用winforms进行了一些测试,但现在我陷入了困境:
我的观点是从数据库运行查询,而查询未完成,我想在表单上显示加载gif。
这是查询数据库的方法:
public static async Task<List<string>> GetItensFromDatabase()
{
List<string> names = new List<string>();
using (ServerConn)
{
ServerConn.Open();
SqlCommand cmd = new SqlCommand("Select * From Names", ServerConn);
var ds = new DataSet();
var adapter = new SqlDataAdapter(cmd);
adapter.Fill(ds); // this call lasts about 1 minute
foreach (DataRow dr in ds.Tables[0].Rows)
{
names.Add(dr["Name"].ToString());
}
}
return names;
}
我在这里称之为:
private async void button1_Click(object sender, EventArgs e)
{
List<string> itens = null;
itens = await AsyncMethods.GetItensFromDatabase(); // I want that the form dont be stuck here
ShowItensInListView(itens);
}
现在我在旋转的窗体上有一个无所不在的加载图像gif,直到调用方法GetItensFromDatabase,当方法运行时,gif停止,当方法完成gif开始再次旋转时。
那么,有些方法可以在GetItensFromDatabase方法运行时保持gif旋转吗?
答案 0 :(得分:2)
您可以在await
方法中使用async
关键字,但由于没有等待操作,您应该使用{{1}在方法中明确创建Task
}:
TaskFactory
编辑:正如@mmarques所指出的,另一个(更好的)解决方案是使用public static Task<List<string>> GetItensFromDatabase()
{
return Task.Factory.StartNew<List<string>>(() =>
{
List<string> names = new List<string>();
using (ServerConn)
{
ServerConn.Open();
SqlCommand cmd = new SqlCommand("Select * From Names", ServerConn);
var ds = new DataSet();
var adapter = new SqlDataAdapter(cmd);
adapter.Fill(ds); // this call lasts about 1 minute
foreach (DataRow dr in ds.Tables[0].Rows)
{
names.Add(dr["Name"].ToString());
}
}
return names;
});
}
而不是SqlDataReader
。原因是SqlDataAdapter
有SqlDataReader
个方法可用 - 这意味着您不需要使用async
来阻止线程池中的新线程,您可以使用TaskFactory
和async
。
await