C# 等待后的代码运行两次

C# 等待后的代码运行两次,c#,.net,asynchronous,async-await,dapper,C#,.net,Asynchronous,Async Await,Dapper,我一直在开发一个Windows窗体应用程序,对于DB端,我正在使用Dapper。 我试图解决的问题是异步执行带参数的存储过程,这样应用程序的执行就不会停止,一旦执行完成,我应该能够向用户显示一条消息 这是调用存储过程的函数(ExceptionData不是这个词的通常含义。它在我的业务逻辑中有其他含义) 当我调试代码时。第一次执行命中 等待代表加载例外数据(今天) 它再次返回单击事件开始,并返回等待行。 之后,执行开始,等待完成后,显示消息。 但在显示调试器指向 如果(结果==真) 当我向前一步时

我一直在开发一个Windows窗体应用程序,对于DB端,我正在使用Dapper。 我试图解决的问题是异步执行带参数的存储过程,这样应用程序的执行就不会停止,一旦执行完成,我应该能够向用户显示一条消息

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

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

等待代表加载例外数据(今天)

它再次返回单击事件开始,并返回等待行。 之后,执行开始,等待完成后,显示消息。 但在显示调试器指向

如果(结果==真) 当我向前一步时,它会进入其中并再次显示消息


我不熟悉Async/Wait,这一切可能只是我犯的一个愚蠢的错误。但是当执行
wait\u connection.ExecuteAsync(…)
时(因为它肯定不会同步完成),控制返回给调用者(
bool result=wait\u rep.Load\u ExceptionData(今天);
),这也会将控制返回给调用者

connection.ExecuteAsync(…)
完成时,
Load\u ExceptionData
方法的继续将发布到同步上下文

\u rep.Load\u ExceptionData(今天)
完成时,
todayToolStripMenuItem\u Click
方法的继续将发布到同步上下文中


我相信这就是你所看到的。

等待连接执行ExecuteAsync(…)
时(因为它肯定不会同步完成),控件返回给调用方(
bool result=wait(等待代表加载例外数据(今天);
),这也会将控件返回给调用方

connection.ExecuteAsync(…)
完成时,
Load\u ExceptionData
方法的继续将发布到同步上下文

\u rep.Load\u ExceptionData(今天)
完成时,
todayToolStripMenuItem\u Click
方法的继续将发布到同步上下文中


我相信这就是你们看到的。

好了,伙计们,我已经解决了问题。我会分享,这样就不会有人像我一样犯同样的错误

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

我做错的是

todayToolStripMenuItem.Click+=todayToolStripMenuItem\u Click

我曾两次将其添加到Click中

  • 有一次,它隐式地添加到表单的开头 在设计视图中单击控件时。它在您的代码中添加其“甚至点击”,并在窗体的设计器中指定它
  • 第二次,我自己明确地添加了它 检查代码中的行
解决方案是在将事件添加到click之前删除它,这样它就不会添加两次
干杯

好了,伙计们,我已经解决了问题。我会分享,这样就不会有人像我一样犯同样的错误

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

我做错的是

todayToolStripMenuItem.Click+=todayToolStripMenuItem\u Click

我曾两次将其添加到Click中

  • 有一次,它隐式地添加到表单的开头 在设计视图中单击控件时。它在您的代码中添加其“甚至点击”,并在窗体的设计器中指定它
  • 第二次,我自己明确地添加了它 检查代码中的行
解决方案是在将事件添加到click之前删除它,这样它就不会添加两次
干杯

做那样的事

todayToolStripMenuItem.Click-=todayToolStripMenuItem\u Click


谢谢你做那样的事

todayToolStripMenuItem.Click-=todayToolStripMenuItem\u Click


谢谢

代码实际上执行了两次还是只在调试器中显示为那样。添加消息框以确保。@usr Yes它可以运行两次。我得到两个消息框:代码是否实际执行了两次,或者它是否仅在调试器中显示为那样。添加消息框以确保。@usr Yes它可以运行两次。我收到两个消息框,我想这就是发生的事情。但问题是,哪些等待是不必要的,并导致了这一问题。以及如何摆脱它。是的,我想这就是发生的事情。但问题是,哪些等待是不必要的,并导致了这一问题。以及如何摆脱它。
    public async Task<bool> Load_ExceptionData(DateTime t)
    {
        IDbTransaction trans = null;
        try
        {
            trans = _connection.BeginTransaction();

            DynamicParameters prms = new DynamicParameters();
            prms.Add("Today", t ,DbType.Date);

            await _connection.ExecuteAsync("usp_CC_Load_ExceptionTable",
                                                    prms,
                                                    trans,
                                                    commandTimeout: 0,
                                                    commandType: CommandType.StoredProcedure
                                                    );


            trans.Commit();
            return true;                         
        }
        catch (Exception)
        {
            trans.Rollback();
            return false;
        }
    }
    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);
        }

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

    }