【问题标题】:Winform - changing a method to async/awaitWinform - 将方法更改为异步/等待
【发布时间】:2016-06-03 02:27:17
【问题描述】:

我有一个 winform 和六个 listbox 并排。在每个listbox 下都有一个textbox 和一个Button,标记为“添加”。当您在textbox 中添加一些内容并按下添加按钮时,使用EF,我会为listbox 更新一个表,然后我将dataBind 重新设置为listbox。这是添加按钮的事件处理程序之一的示例:

private void btnOfferType_Click(object sender, EventArgs e)
{
    TypeCategoryAdd("OfferType", tbOfferType.Text.Trim());
}

TypeCategoryAdd 函数如下所示。我想这样做(注意await):

private async void btnOfferType_Click(object sender, EventArgs e)
{
    await TypeCategoryAdd("OfferType", tbOfferType.Text.Trim());
}

我需要做什么才能使TypeCategoryAdd 函数在不同的上下文中运行,以便winform UI 在数据库更新发生时不会冻结?

private void TypeCategoryAdd (string table, string item)
{
    if (string.IsNullOrEmpty(item)) return;

    using (MenuGenerator.NewArchMenuGeneratorEntities con = new NewArchMenuGeneratorEntities())
    {
        switch (table)
        {
            case "OfferType":
                if (con.OfferTypes.Any(x=>x.Name == item))
                {
                    MessageBox.Show("There is already a " + item + " on the list!");
                    tbOfferType.Text = "";
                    return;
                }
                OfferType ot = new OfferType();
                ot.Name = item;
                con.OfferTypes.Add(ot);
                try
                {
                    con.SaveChanges();
                    tbOfferType.Text = "";
                    lstOfferType.DataSource = con.OfferTypes.OrderBy(x=>x.Id).ToList();                    
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error " + ex.ToString());
                }
                break;                

            }
            return;
        }

【问题讨论】:

  • 请将代码缩减为minimum possible to reproduce the error
  • @StephenCleary 完成。将代码减少到一个case。感谢您的帮助、精彩的文章、您的博客和您的书。
  • @StephenCleary 一些拥有 3K 代表点数的人试图帮助我,但他尝试的任何事情都会产生某种错误。所以他决定完全删除整个答案。所以我回到第一方。如果您对我的问题有任何建议,我将不胜感激。
  • 我发布的链接描述了一个最小的、完整的、可验证的示例。这就是你需要的。就目前而言,它还不完整(即,我无法将其复制到新项目中并查看您所看到的内容)。

标签: c# multithreading winforms async-await


【解决方案1】:

如何利用 EF 6 中的 async 方法:

private async Task TypeCategoryAdd (string table, string item)
{
    if (string.IsNullOrEmpty(item)) return;

    using (MenuGenerator.NewArchMenuGeneratorEntities con = new NewArchMenuGeneratorEntities())
    {
        switch (table)
        {
            case "OfferType":
                if (await con.OfferTypes.AnyAsync(x=>x.Name == item))
                {
                    MessageBox.Show("There is already a " + item + " on the list!");
                    tbOfferType.Text = "";
                    return;
                }
                OfferType ot = new OfferType();
                ot.Name = item;
                con.OfferTypes.Add(ot);
                try
                {
                    await con.SaveChangesAsync();
                    tbOfferType.Text = "";
                    lstOfferType.DataSource = await con.OfferTypes.OrderBy(x=>x.Id).ToListAsync();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error " + ex.ToString());
                }
                break;                

            }
            return;
        }
    }
}

【讨论】:

  • 我正在使用 ADO.Net 实体框架工作。可悲的是它没有附带SaveChangesAsync
  • @Zuzlx Version 6 does.如果你使用的是旧版本,不能升级吗?
  • 看来我别无选择,只能升级。否则,(也许我在这里错了)我们必须将东西包装在 Task 中,以便我们可以将 awaitable 的对象返回给调用者。
【解决方案2】:

您可以将您的数据库访问权限封装在 Taskawait 中。

private async void btnOfferType_Click(object sender, EventArgs e)
{
    await Task.Run(()=>TypeCategoryAdd("OfferType", tbOfferType.Text.Trim()));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多