使用async/await时UI仍然冻结

Ros*_*ana 3 c# asynchronous winforms

我不是在同步操作方面的专家,并希望有人可以帮助我指出问题所在.

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

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;
}
Run Code Online (Sandbox Code Playgroud)

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

int _recordsAffected = await MyClass.ExecuteNonQueryRawSQLAsync("INSERT....");
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*ell 5

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

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

未经测试,但可能是:

await Task.StartNew(_conn.Open);
Run Code Online (Sandbox Code Playgroud)

  • @Rossana:我之前的评论有一个链接到我的博客,我解释了为什么我不推荐`StartNew`.我建议你按照Marc建议的方式更改你的包装,但是使用`Run`代替`Factory.StartNew`. (2认同)
  • @Rossana:这是Marc在回答中描述的问题.总而言之,许多.NET网络调用实际上并非*异步. (2认同)