【问题标题】:Using await with a TableAdapter将 await 与 TableAdapter 一起使用
【发布时间】:2011-08-20 04:30:11
【问题描述】:

我最近开始使用 Async CTP,虽然我发现它对自编码类等非常有用,但在尝试使用生成的代码(特别是生成的 TableAdapter)实现它时遇到了一些障碍当您使用数据集时。

我有一个使用 .Fill 调用来填充 DataGrids 和 Databindings 的应用程序。由于 .Fill 块和我的用户需要能够在此过程中与应用程序交互,因此我认为 Async CTP 是一个理想的解决方案。

不幸的是,我似乎无法将它与生成的 TableAdpters 一起使用,而无需自己编写代码。我有哪些选择?

【问题讨论】:

  • 您找到了可行的解决方案吗?
  • 不,我从来没有找到解决方案。我仍然希望在.Net5 中为这样的事情实现异步的东西。这会让我的生活更轻松。
  • 那太好了!我花了整整一周的时间试图解决这个问题,但我什么也做不了!令人沮丧!

标签: c# asynchronous tableadapter


【解决方案1】:

问题在于 TableAdapter 没有异步 Fill 方法。这意味着要让您的 Fill 在不阻塞 UI 线程的情况下运行,您必须在其上运行一个工作线程。异步 CTP 对此没有帮助 - 它使使用异步 API 变得更容易,但如果 API 的异步版本不存在,它将无济于事。

但是在工作线程上运行填充应该和启动任务一样简单:

public Task FillAsync()
{
    return Task.Factory.StartNew( () =>
    {
        adapter1.Fill(ds1);
        adapter2.Fill(ds2);
        // etc
    });
}

现在异步 CTP 派上用场的地方是,如果您需要在填充后做一些额外的工作,并且您需要在 UI 线程上进行这些额外的工作:

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

默认情况下,在 WinForms/WPF/Silverlight 应用程序中运行时,当您等待时,它将在 UI 线程上恢复,因此在后台线程上完成填充工作后,将在您的 UI 线程上调用 refreshControls。

有一个涵盖此here 的示例: (UI 响应性 -> CPU 绑定任务期间的响应式 UI)

【讨论】:

  • 我和 OP 有同样的问题,并尝试了你的建议,但我无法让它发挥作用。它不会引发任何错误,但不会以异步方法更新数据网格。有什么想法吗?
  • 你需要重新绑定你的 UI。在上面的示例中,我假设 refreshControls 方法会触发您的 UI 刷新。
【解决方案2】:
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);
            });
        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-05
    • 2019-04-15
    • 2014-06-19
    • 2018-01-14
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多