简体   繁体   中英

Canceling DataAdapter.Fill()

Scenario: We have a DataGridView which is attached to DataAdapter (datatable), we load the data in datatable using (adapter.fill(query, datatable)) in a separate thread (using delegate and beginInvoke) and once the data is loaded we attached that datatable to datagridview (in the main thread)

Is there a way we can check if fill() is still executing and cancel it.

Real scenario: User click on the user name and corresponding data is loaded in the datagrid. Sometime, user is impatient and click on the another user (here I want to cancel the previous fill and start a new fill)

UPDATE: We keep two DataApdaters (and two DataTables) and we attach one datatable to datagridview and start loading data to another datatable asynchronously. When data is loaded we simply bind the datagridview to DataTable which we just filled (and start loading the previous datable asynchronously) This way UI will always get the current data (without user waiting on UI to refresh or hang)

You can provide a SqlCommand to adapter constructor and invoke a Cancel method on it. There is a raw template:

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();
        ...
    }
}

There is no facility to safely cancel DataAdapter.Fill() .

To work around this, one option would be to implement a mechanism that can cause these unwanted fills to be ignored and so not reflected in the UI. I would recommend incrementing a counter at the beginning of an async operation and passing that state to your asyn action. Your async action can then check its counter value against the current counter when it finishes. If the counters are not equal, then do not update the UI.

If you see a pattern where the user rapidly clicks between users and lots of requests get discarded, then implement a timer mechanism whereby you only retrieve data if the user stays on the selection for a minimum amount of time.

I did a quick search and found this: cancel a DataAdapter.Fill There seems to be no way to get around handling an exception, as the author of the code states.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM