C# 使用等待和异步在长方法运行时释放UI线程
我开始探索c 5.0中的async和wait关键字,所以我使用winforms进行了一些测试,但现在我陷入了一个困境: 我的目的是从数据库运行查询,当查询未完成时,我想在表单上显示正在加载的gif 这是查询数据库的方法:C# 使用等待和异步在长方法运行时释放UI线程,c#,multithreading,asynchronous,async-await,C#,Multithreading,Asynchronous,Async Await,我开始探索c 5.0中的async和wait关键字,所以我使用winforms进行了一些测试,但现在我陷入了一个困境: 我的目的是从数据库运行查询,当查询未完成时,我想在表单上显示正在加载的gif 这是查询数据库的方法: public static async Task<List<string>> GetItensFromDatabase() { List<string> names = new List<string>()
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旋转?您可以在异步方法中使用wait关键字,但由于没有等待操作,因此应该使用TaskFactory在方法中显式创建任务:
仅将async拍打到一个方法不会使其自动异步/非阻塞…请您解释一下您的意思,您可以在async方法中使用wait关键字,但由于没有等待操作。。。。所以,你想说的是,如果我有一些长循环,例如,我可以在循环中使用wait关键字来释放Ui线程?类似这样的事情:等待任务@johnnycardy,您不应该使用Task.Factory.StartNew将同步IO绑定操作卸载到池线程。您应该改为使用ADO.NET提供的异步API,并等待其结果。ADO.NET提供的异步API在哪里?我没有遇到过any@johnnycardy,至少有两个选项:1、2个现有的异步API,如,可以很容易地将其转换为可等待的任务样式API。@johnnycardy:当您使用异步时,请考虑每个方法都在做什么,以及是否有异步方式来做。例如,解决方案应该在循环中使用ServerConn.OpenAsync和ReadAsync,而不是DataTable.Load。
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;
});
}
public static async Task<List<string>> GetItensFromDatabase()
{
List<string> names = new List<string>();
using (ServerConn)
{
using (SqlCommand cmd = new SqlCommand("Select * From Names", ServerConn))
{
ServerConn.Open();
SqlDataReader reader = await cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection);
if (reader.HasRows)
{
DataTable dt = new DataTable();
dt.Load(reader);
foreach (DataRow dr in dt.Rows)
{
names.Add(dr["Name"].ToString());
}
}
}
}
return names;
}