问题
I recently began using the Async CTP and while I have found it quite useful with Self Coded classes and the like, I have run into a bit of a snag when trying to implement it with Generated Code, specifically the TableAdapters that are generated when you work with a Dataset.
I have an application that uses .Fill calls quite a bit to populate DataGrids and Databindings. Since .Fill blocks and my users need to be able to interact with the application while this is going on, I see the Async CTP to be an Ideal solution.
Unfortunately, I cannot seem to use it with the generated TableAdpters without having to code them myself. What are my options?
回答1:
The problem is that TableAdapters don't have asynchronous Fill methods. This means to get your Fill to run without blocking the UI thread you will have to run on it a worker thread. The async CTP doesn't help you with this - it makes it easier to consume async APIs but it won't help if the async version of the API doesn't exist.
But running the fill on a worker thread should be as easy as spinning up a Task:
public Task FillAsync()
{
return Task.Factory.StartNew( () =>
{
adapter1.Fill(ds1);
adapter2.Fill(ds2);
// etc
});
}
Now where the async CTP will come in handy is if you need to do some additional work after the fills and you need that additional work to happen on the UI thread:
public async Task RebindUI()
{
// Do stuff on UI thread
// Fill datasets on background thread
await FillAsync();
// When fill is complete do some more work on the UI thread
refreshControls();
}
By default when running in a WinForms/WPF/Silverlight app, when you await it will resume on the UI thread, so refreshControls will be called on your UI thread after the Fill work is done on a background thread.
There's a sample that covers this here: (UI Responsiveness -> Responsive UI during CPU bound tasks)
来源:https://stackoverflow.com/questions/7129662/using-await-with-a-tableadapter