在C#中执行模拟事件调用的顺序

时间:2012-05-31 18:41:22

标签: c# events race-condition

我有一个C#程序,它有两个元素,一个TreeView和一个DataGridView以及两个EventHandelrs。在TreeView中选择一个项目时,DataGridView会显示一些显示某些信息的表格,并且可以由用户进行编辑。 TreeView中的每个项目都有自己的唯一表。当用户在DataGridView上取消注意时,软件底层软件模型会更新(保存用户所做的更改):

aDataGridView_Leave(object sender, EventArgs e)
{
     //Update the software model (save the current DataGridView)
}

aTreeView_AfterSelect(object sender, EventArgs e)
{
    //Update the table that is shown in aDataGridView
}

我的问题是,如果用户通过在TreeView中选择一个不同的项目来解除对DataGridView的关注,那么我基本上会在这些事件首先发生之间存在竞争条件(即使这只是在一个线程上)。显然,在这种情况下,我希望首先触发DataGridView_Leave事件,或者在保存更改之前,用户所做的更改会被正在加载的新表吹走。

有没有优雅的方法来强制执行首先发生的事件?

3 个答案:

答案 0 :(得分:0)

立即想到的是某种反击。为每个事件调用分配一个数字并存储最后一个处理过的数字这样你可以检查它是否是旧事件并忽略它。我还没有看到它在C#中使用过,但是当网络延迟经常导致这种情况时,很多次使用AJAX。

答案 1 :(得分:0)

听起来你可以通过在必须保存更改时保持isDirty布尔值来解决这个问题。您需要自己跟踪,例如在属性设置器中。检查isDirty中的aTreeView_AfterSelect并在必要时保存,并在aDataGridView_Leave中保存,以便在没有更改时不进行保存。

这应该可行,但听起来你的设置有点笨拙,而且当一个元素失去焦点时,用户可能会违反直觉,保存更改。

答案 2 :(得分:0)

我创建了一个简单的Windows窗体应用程序,其中包含树视图,网格视图和文本框,用于记录发生的事件。当你离开gridview时,它的leave事件总是在selectview之后的treeview之前触发。

您是否异步保存gridview中的数据?我可以看到你是否异步保存,然后在你的异步方法抓取数据以从网格中保存之后,select会触发之后的树视图。

如果是这种情况,请将gridviews数据推送到堆栈,然后在执行保存的方法中将其弹出。