【问题标题】:await ExecuteNonQueryAsync() still blocks my UI等待 ExecuteNonQueryAsync() 仍然阻塞我的用户界面
【发布时间】:2015-07-15 13:01:29
【问题描述】:

我发现我的 C# 应用程序 UI 在调用异步方法时挂起,我不知道为什么。

private async void selectCSVFileButton_Click(object sender, EventArgs e)
{
    ... 
    var results = await ntz.getProductNames();
    ...
}
...
public async Task<List<string[]>> getProductNames()
{
    string fmt = "DRIVER={{NetezzaSQL}};SERVER={0};PORT={1};DATABASE={2};UID={3};PWD={4};";
    ntz = new OdbcConnection(string.Format(fmt, server, port, db, user, password));
    await ntz.OpenAsync();
    qry = "SELECT * FROM ak_db_1 WHERE prod_name_desc='Unknown'";
    OdbcCommand cmd = ntz.CreateCommand();
    cmd.CommandTimeout = 600;
    cmd.CommandText = qry;
    await cmd.ExecuteNonQueryAsync();
    ...
}

我的应用程序完全挂起(UI 无响应),直到 cmd.ExecuteNonQueryAsync 完成。有什么想法吗?

【问题讨论】:

    标签: c# sql asynchronous netezza


    【解决方案1】:

    每the documentationOdbcCommand.ExecuteNonQueryAsync:

    提供者应该使用适当的实现来覆盖。可以选择忽略取消令牌。 默认实现调用同步的ExecuteNonQuery方法并返回一个完成的任务,阻塞调用线程。

    派生命令(例如 SQL Server 的 SqlCommand)do 会覆盖此命令,因此命令异步执行。

    如果您想避免阻塞 UI 线程,则必须在线程池线程上执行此操作:

    var results = await Task.Run(() => ntz.getProductNames());
    

    鉴于异步方法没有实现,只是简单地委托给它们的同步等效方法,因此首先将 getProductNames 更改为使用同步方法可能是有意义的。

    【讨论】:

    • 非常感谢查尔斯,我完全错过了!
    【解决方案2】:

    尝试添加这个,而不是await ntz.OpenAsync();.

    await Task.StartNew(ntz.Open);
    

    【讨论】:

    • 你的意思是Task.Run()还是Task.Factory.StartNew()?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多