使用 async/await 时 UI 仍然冻结
本文关键字:冻结 UI async await 使用 | 更新日期: 2023-09-27 18:34:32
我不是非同步操作方面的专家,希望有人能帮我指出问题。
在我的一种方法中,我写了一个包装器,
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 冻结。我的包装中缺少哪些内容?或者我需要做任何其他需要的初始化吗?
从苦内存来看,TCP 套接字有一个非常相似的问题 - 基本上,名称解析是同步执行的,即使对于异步操作也是如此。有两种方法可以解决此问题:
- 使用 IP 地址而不是名称
- 确保从工作线程启动
Open*
/Connect*
/任何内容 - 也许Task.StartNew
未经测试,但大概:
await Task.StartNew(_conn.Open);
await "somemethod" 并不意味着该方法是异步调用的。您仍在执行常规方法调用,该方法将像任何其他方法一样运行,直到被调用的方法决定返回表示异步操作的任务,然后等待该任务。
如果该方法在返回可等待任务之前做了一堆耗时的事情,您可以使用 TaskFactory.Startnew(( 调用它。