Code after await runs twice

.net async-await asynchronous c# dapper

Question

i have been developing a Windows form application and for DB end i am using Dapper. The problem i am trying to solve is to execute a parametered stored procedure asynchronously so that my the execution of the application is not stopped and once the execution is done i should be able to show user a message

This is the function which calls the stored procedure (ExceptionData is not the usual meaning of the word. it has some other meaning in my business logic)

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

And this function is called in trigger to a click

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

    }

When i debug the code. the first time execution hits

await _rep.Load_ExceptionData(today);

it goes back again to the click event start and comes back to the await line. After that the execution starts and once await is done the message is shown. But after showing debugger points to

if (result == true) line and when i step forward it goes inside it and again Shows the message

I am new to Async/await and this all may just be a dumb mistake i did. But still i will appreciate the answer

Accepted Answer

Alright guys i have figured out the problem. I will share so that no one else does the same mistake like i did.

So i had a function which was called on form load and was responsible to check whether the data which i am going to load is already present in the table. If "Yes" then remove the click event from the ToolStripMenuItem and if "No" then Add it.

What i was doing wrong was

todayToolStripMenuItem.Click += todayToolStripMenuItem_Click;

i was adding it twice to the Click

  • One time implicitly it was added in start of the form

    When you click on the control from the design view. It adds its click even in your code and the assign it in the designer of the form
  • Second time i was explicitly adding it my self

    check the line in the code

Solution was to remove the event before adding it to click so that it doesnt add twice

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

    }

Cheers!


Popular Answer

Do something like that

todayToolStripMenuItem.Click -= todayToolStripMenuItem_Click;

Thanks



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why