C# 使用async/await时UI仍然冻结
我不是非同步操作方面的专家,希望有人能帮我指出问题所在 在我的一个方法中,我编写了一个包装器C# 使用async/await时UI仍然冻结,c#,winforms,asynchronous,C#,Winforms,Asynchronous,我不是非同步操作方面的专家,希望有人能帮我指出问题所在 在我的一个方法中,我编写了一个包装器 public static async Task<int> ExecuteNonQueryRawSQLAsync(string sqlStatement) { int _returnValue = -1; using (SqlConnection _conn = new SqlConnection("connectionString")) { usin
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冻结。我的包装里少了什么?或者我还需要进行任何其他必要的初始化吗?从苦涩的记忆中,TCP套接字有一个非常类似的问题-基本上,名称解析是同步执行的,即使是异步操作。有两种解决方法:
- 使用IP地址而不是名称
- 确保从工作线程启动
/打开*
/任何任务-可能是连接*
任务。开始新建
await Task.StartNew(_conn.Open);
wait“somemethod”并不意味着该方法被异步调用。您仍在执行常规方法调用,该调用将像其他方法一样运行,直到被调用的方法决定返回表示异步操作的任务,然后等待
如果该方法在返回等待的任务之前做了大量耗时的工作,那么可以使用调用它。在中调用
ExecuteNonQueryRawSQLAsync
的方法是async
?@ChrisMantle它是我的包装器的名称。在包装器中,有一个异步方法ExecuteNonQueryAsync()
。有关于这个marc的文档吗?还是你凭经验发现的?@SriramSakthivel我还没看过;基本上,我发现这很难,因为我碰到了一个非常类似的问题——IIRC,然后我偷看了一下reflector@Rossana:我之前的评论有一个到我博客的链接,我在这里解释了为什么我不推荐StartNew
。我建议您按照Marc建议的方式更改包装器,但使用Run
而不是Factory。StartNew
@Rossana:是的,这就是我的意思。@Rossana:这与Marc在回答中描述的问题相同。总而言之,很多.NET网络调用实际上都不是异步的。那么,我的回答与这个有什么不同呢@Rossana注意到帖子上说的是“正确编写的方法”。如果该方法在创建任务时阻塞,则说明该方法未“正确写入”。异步方法应该立即返回。如果任务的创建非常耗时(它需要解析DNS命名或其他什么),那么创建本身应该包装在一个新任务中,以便客户端将整个任务视为一个可等待的任务。
await Task.StartNew(_conn.Open);