开发者

Using await with a TableAdapter

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 t开发者_StackOverflow社区he 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?


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)


namespace AsyncGrid
{
    public partial class Form1 : Form
    {
        SolarDataLogTableAdapter ta = new SolarDataLogTableAdapter();
        SolarDataLogDataTable dt = new SolarDataLogDataTable();

        BindingSource bs = new BindingSource();

        public Form1()
        {
            InitializeComponent();

            bs.DataSource = dt;
            dataGridView1.DataSource = bs;
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            dataGridView1.Enabled = false;

            await FillAsync();
            bs.ResetBindings(true);
        
            dataGridView1.Enabled = true;
        }

        public Task FillAsync()
        {
            return Task.Run(() =>
            {
                ta.Fill(dt);
            });
        }

    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜