取消DataAdapter.Fill()

时间:2011-08-17 16:11:11

标签: c# ado.net

方案: 我们有一个附加到DataAdapter(datatable)的DataGridView,我们在一个单独的线程中使用(adapter.fill(query,datatable))在datatable中加载数据(使用delegate和beginInvoke),一旦数据加载,我们附加了数据表到datagridview(在主线程中)

我们有办法检查fill()是否仍在执行并取消它。

真实场景: 用户单击用户名,相应的数据将加载到数据网格中。有时,用户不耐烦并点击另一个用户(这里我想取消之前的填充并开始新的填充)

更新: 我们保留两个DataApdater(和两个DataTables),我们将一个数据表附加到datagridview,并开始异步地将数据加载到另一个数据表。加载数据时,我们只需将datagridview绑定到我们刚刚填充的DataTable(并开始异步加载以前的数据)这样UI将始终获取当前数据(无需用户在UI上等待刷新或挂起)

3 个答案:

答案 0 :(得分:1)

您可以为适配器构造函数提供SqlCommand并在其上调用Cancel方法。 有一个原始模板:

class Model 
{
    private SqlCommand loadUserCommand;
    private DataTable userData;

    public void LoadUser(string userId) 
    {
        loadUserCommand = GetUserLoadCommandForUserID(userId);
        userData = new DataTable("userData");
        using (var adapter = new SqlDataAdapter(loadUserCommand)) 
        {
            adapter.Fill(userData);
        }
    }

    public void AbortLoadUser()
    {
        if (loadUserCommand!= null)
            loadUserCommand.Cancel();
    }


    private SqlCommand GetUserLoadCommandForUserID(string userId)
    {
        var connection = new SqlConnection("...");
        var command = connection.CreateCommand();
        ...
    }
}

答案 1 :(得分:0)

无法安全取消DataAdapter.Fill()

要解决此问题,一个选项是实现一种机制,可以忽略这些不需要的填充,因此不会反映在UI中。我建议在异步操作开始时递增计数器并将该状态传递给asyn操作。然后,您的异步操作可以在完成时针对当前计数器检查其计数器值。如果计数器不相等,则不要更新UI。

如果您看到用户在用户之间快速点击并且大量请求被丢弃的模式,那么实施一个计时器机制,只有当用户在选择中保持最短时间时才能检索数据。

答案 2 :(得分:0)

我做了一个快速搜索并找到了这个:cancel a DataAdapter.Fill似乎没有办法绕过处理异常,正如代码的作者所说。