使用async / await时UI仍然冻结

时间:2013-10-08 08:13:15

标签: c# winforms asynchronous

我在异步操作方面不是专家,希望有人可以帮我指出问题。

在我的一个方法中,我编写了一个包装器,

public static async Task<int> ExecuteNonQueryRawSQLAsync(string sqlStatement)
{
    int _returnValue = -1;
    using (SqlConnection _conn = new SqlConnection("connectionString"))
    {
        using (SqlCommand _comm = new SqlCommand())
        {
            _comm.Connection = _conn;
            _comm.CommandText = sqlStatement;
            _comm.CommandType = CommandType.Text;

            // other codes on setting parameter

            try
            {
                await _conn.OpenAsync();
                _returnValue = Convert.ToInt32(await _comm.ExecuteNonQueryAsync());
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
    return _returnValue;
}

在我的UI中,我调用了这样的方法,

int _recordsAffected = await MyClass.ExecuteNonQueryRawSQLAsync("INSERT....");

为了测试它是否真的有效,我试图在连接字符串中提供一个无效的数据库服务器地址,以便它继续搜索,直到它抛出异常。

当程序仍在连接时,UI会冻结。我的包装中缺少什么东西?或者我需要做任何其他需要的初始化吗?

2 个答案:

答案 0 :(得分:5)

从痛苦的内存中,TCP套接字有一个非常类似的问题 - 基本上,名称解析是同步执行的,即使对于异步操作也是如此。有两种方法:

  • 使用IP地址而不是名称
  • 确保从工作线程启动Open* / Connect* /任何 - 也许Task.StartNew

未经测试,但可能是:

await Task.StartNew(_conn.Open);

答案 1 :(得分:0)

等待“somemethod”并不意味着该方法被异步调用。您仍在执行常规方法调用,该方法将像任何其他方法一样运行,直到被调用的方法决定返回表示异步操作的任务,然后等待。

如果该方法在返回等待任务之前执行了大量耗时的操作,则可以使用TaskFactory.Startnew()调用它。