Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用等待和异步在长方法运行时释放UI线程_C#_Multithreading_Asynchronous_Async Await - Fatal编程技术网

C# 使用等待和异步在长方法运行时释放UI线程

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>()

我开始探索c 5.0中的async和wait关键字,所以我使用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旋转?

您可以在异步方法中使用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;
}