等待运行两次后的代码

时间:2016-04-25 15:49:02

标签: c# .net asynchronous async-await dapper

我一直在开发Windows表单应用程序,对于DB结束我使用的是Dapper。 我试图解决的问题是异步执行参数化存储过程,以便我的应用程序执行不会停止,一旦执行完毕,我应该能够向用户显示一条消息

这是调用存储过程的函数(ExceptionData不是单词的通常含义。它在我的业务逻辑中有一些其他含义)

    private async void todayToolStripMenuItem_Click(object sender, EventArgs e)
    {
        try
        {
            DateTime today;
            today = Convert.ToDateTime("3/16/2016");//DateTime.Today;
            CycleCountRepository _rep = new CycleCountRepository(); // Repository

            todayToolStripMenuItem.Click -= todayToolStripMenuItem_Click; // Disabling the button so while in execution not clicked again

            if (Enabled && _rep.Check_CycleCountToday(today)) // Checks if the data is already present for the date
            {
                todayToolStripMenuItem.Image = Properties.Resources.progress;
                bool result = await _rep.Load_ExceptionData(today); // the async function
                if (result == true)
                {
                    ShowMessage("Data Load Successfully! Date: " + today, "Success", MessageBoxIcon.None); // This message is shown twice
                }
                else
                {
                    ShowMessage("Data Load Error! Date: " + today, "Warning", MessageBoxIcon.Warning);
                }
                CheckTodayLoad();
            }
            else
            {
                ShowMessage("Nothing to Load! No locations scanned today!", "Warning", MessageBoxIcon.Warning);
            }
        }
        catch (Exception ex)
        {
            ShowMessage(ex.Message, "Warning", MessageBoxIcon.Warning);
        }

    }

此功能在触发器中调用

{{1}}

当我调试代码时。第一次执行命中

  

等待_rep.Load_ExceptionData(今天);

它再次返回到click事件开始并返回到await行。 之后执行开始,一旦等待完成,就会显示消息。 但在显示调试器指向

之后
  

if(result == true)   行,当我向前迈进它进入它并再次显示消息

我是Async / await的新手,这可能只是我做的一个愚蠢的错误。但我仍然会欣赏答案

3 个答案:

答案 0 :(得分:2)

好吧,伙计们我已经找到了问题所在。我将分享,以便没有其他人像我一样犯同样的错误。

所以我有一个在表单加载时调用的函数,负责检查我要加载的数据是否已经存在于表中。如果"是"然后从ToolStripMenuItem中删除click事件,如果" No"然后添加它。

我做错了是

todayToolStripMenuItem.Click += todayToolStripMenuItem_Click;

我在Click中添加了两次

  
      
  • 有一次隐含地将其添加到表单的开头

         从设计视图中单击控件时。它甚至在您的代码中添加了它的点击,并将其分配给表单的设计者
  •   
  • 第二次我明确地添加了我自己的

         检查代码中的行
  •   

解决方案是在将事件添加到单击之前删除该事件,以便它不会添加两次

    private void CheckTodayLoad()
    {
        DateTime today;
        today = Convert.ToDateTime(DateTime.Today); 
        CycleCountRepository _rep = new CycleCountRepository();
        if (_rep.CheckTodayLoaded(today))
        {
            todayToolStripMenuItem.Image = Properties.Resources.checkmark;
            todayToolStripMenuItem.Text = "Today " + "[" + today.ToShortDateString() + "]" + " : Loaded";
            todayToolStripMenuItem.Click -= todayToolStripMenuItem_Click;

        }
        else
        {
            todayToolStripMenuItem.Image = SystemIcons.Warning.ToBitmap();
            todayToolStripMenuItem.Text = "Today " + "[" + today.ToShortDateString() + "]" + " : Not Loaded";
            todayToolStripMenuItem.Click -= todayToolStripMenuItem_Click; // Just to make sure it is not registered twice. Previously this line wasnt there
            todayToolStripMenuItem.Click += todayToolStripMenuItem_Click;
        }

    }

干杯!

答案 1 :(得分:1)

做那样的事

todayToolStripMenuItem.Click -= todayToolStripMenuItem_Click;

由于

答案 2 :(得分:0)

执行await _connection.ExecuteAsync(...)时(因为它确实不会同步完成),控制权将返回给调用者(bool result = await _rep.Load_ExceptionData(today);),调用者也会将控制权返回给调用者。

connection.ExecuteAsync(...)完成时,Load_ExceptionData方法的延续将发布到同步上下文。

_rep.Load_ExceptionData(today)完成时,todayToolStripMenuItem_Click方法的延续将发布到同步上下文。

我确定你所看到的是什么。