取消DataAdapter.Fill()

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

有没有办法可以检查fill()是否仍在执行并取消它。

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

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

您可以为适配器构造函数提供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(); ... } } 

没有安全取消DataAdapter.Fill()

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

如果您看到用户在用户之间快速点击并且大量请求被丢弃的模式,则实施计时器机制,只有当用户在选择上停留最少时间时才会检索数据。

我做了一个快速搜索,发现这个: 取消一个DataAdapter.Fill似乎没有办法绕过处理exception,正如代码的作者所说。