await 运行两次后的代码
Code after await runs twice
我一直在开发一个 Windows 表单应用程序,对于数据库端,我正在使用 Dapper。
我要解决的问题是异步执行参数化存储过程,这样应用程序的执行就不会停止,一旦执行完成,我应该能够向用户显示一条消息
这是调用存储过程的函数(ExceptionData不是这个词的通常含义,它在我的业务逻辑中有其他含义)
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);
}
}
当我调试代码时。第一次执行命中
await _rep.Load_ExceptionData(today);
它再次返回到点击事件开始并返回到等待行。
之后执行开始,等待完成后显示消息。
但是在显示调试器指向
之后
if (result == true)
line and when i step forward it goes inside it and again Shows the message
我是 Async/await 的新手,这一切可能只是我犯的一个愚蠢的错误。但我还是会很感激你的回答
当执行 await _connection.ExecuteAsync(...)
时(因为它肯定不会同步完成),控制权返回给调用者 (bool result = await _rep.Load_ExceptionData(today);
),后者也 returns 控制权给来电者。
当 connection.ExecuteAsync(...)
完成时,Load_ExceptionData
方法的延续将发布到同步上下文。
当 _rep.Load_ExceptionData(today)
完成时,todayToolStripMenuItem_Click
方法的延续将发布到同步上下文。
我确定这就是您所看到的。
好的伙计们,我已经找到问题了。我会分享,这样就没有人会像我一样犯同样的错误。
所以我有一个在表单加载时调用的函数,负责检查我要加载的数据是否已经存在于 table 中。如果 "Yes" 然后从 ToolStripMenuItem 中删除点击事件,如果 "No" 然后添加它。
我做错的是
todayToolStripMenuItem.Click += todayToolStripMenuItem_Click;
我将它添加到 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
解决方案是在将事件添加到点击之前删除该事件,这样它就不会添加两次
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;
}
}
干杯!
做类似的事情
todayToolStripMenuItem.Click -= todayToolStripMenuItem_Click;
谢谢
我一直在开发一个 Windows 表单应用程序,对于数据库端,我正在使用 Dapper。 我要解决的问题是异步执行参数化存储过程,这样应用程序的执行就不会停止,一旦执行完成,我应该能够向用户显示一条消息
这是调用存储过程的函数(ExceptionData不是这个词的通常含义,它在我的业务逻辑中有其他含义)
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);
}
}
当我调试代码时。第一次执行命中
await _rep.Load_ExceptionData(today);
它再次返回到点击事件开始并返回到等待行。 之后执行开始,等待完成后显示消息。 但是在显示调试器指向
之后if (result == true) line and when i step forward it goes inside it and again Shows the message
我是 Async/await 的新手,这一切可能只是我犯的一个愚蠢的错误。但我还是会很感激你的回答
当执行 await _connection.ExecuteAsync(...)
时(因为它肯定不会同步完成),控制权返回给调用者 (bool result = await _rep.Load_ExceptionData(today);
),后者也 returns 控制权给来电者。
当 connection.ExecuteAsync(...)
完成时,Load_ExceptionData
方法的延续将发布到同步上下文。
当 _rep.Load_ExceptionData(today)
完成时,todayToolStripMenuItem_Click
方法的延续将发布到同步上下文。
我确定这就是您所看到的。
好的伙计们,我已经找到问题了。我会分享,这样就没有人会像我一样犯同样的错误。
所以我有一个在表单加载时调用的函数,负责检查我要加载的数据是否已经存在于 table 中。如果 "Yes" 然后从 ToolStripMenuItem 中删除点击事件,如果 "No" 然后添加它。
我做错的是
todayToolStripMenuItem.Click += todayToolStripMenuItem_Click;
我将它添加到 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 formSecond time i was explicitly adding it my self
check the line in the code
解决方案是在将事件添加到点击之前删除该事件,这样它就不会添加两次
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;
}
}
干杯!
做类似的事情
todayToolStripMenuItem.Click -= todayToolStripMenuItem_Click;
谢谢